# 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 $
###############################################################################
# #
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
********************************************************************
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 $
********************************************************************/
/* 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 */
}
********************************************************************
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 $
********************************************************************/
/* 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
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 $
********************************************************************/
#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{
} 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{
} 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;
/* 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;
********************************************************************
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 $
********************************************************************/
#include <sys/types.h>
#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{
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 */
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 *****/
} 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
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 $
********************************************************************/
} oggpack_buffer;
-/* internal use */
-extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
-extern void _vorbis_block_ripcord(vorbis_block *vb);
-
#endif
# 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 $
###############################################################################
# #
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\
********************************************************************
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 $
********************************************************************/
/* 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 */
********************************************************************
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.
#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;
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);
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));
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;i<VI_WINDOWB;i++){
+ v->window[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;i<vi->modes;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;i<vi->books;i++)
+ vorbis_book_finish(v->fullbooks+i,vi->book_param[i]);
/* initialize the storage vectors to a decent size greater than the
minimum */
/* 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 */
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;i<VI_WINDOWB;i++){
+ if(v->window[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;i<vi->channels;i++)
if(v->pcm[i])free(v->pcm[i]);
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;i<vi->modes;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;i<vi->books;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));
}
}
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 */
********************************************************************
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 $
********************************************************************/
#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);
********************************************************************
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 $
********************************************************************/
}
/* 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);
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);
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. */
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;i<c->entries;i++){
long this=c->lengthlist[i];
long last=c->lengthlist[i-1];
if(this>last){
for(j=last;j<this;j++){
- _oggpack_write(b,i-count,ilog(c->entries-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;i<c->entries;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;i<c->entries*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;i<c->entries;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;i<c->entries;){
- 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;j<num;j++,i++)
- c->lengthlist[i]=length;
+ lengthlist[i]=length;
length++;
}
}
}
/* 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 */
{
for(i=0;i<c->entries;i++){
long ptr=0;
- for(j=0;j<c->lengthlist[i]-1;j++){
- int bit=(c->codelist[i]>>j)&1;
+ for(j=0;j<lengthlist[i]-1;j++){
+ int bit=(codelist[i]>>j)&1;
if(!bit){
if(!ptr0[ptr])
ptr0[ptr]= ++top;
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;i<c->entries*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 */
_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);
/* 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;
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(){
/* 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;i<TESTSIZE;i+=TESTDIM)
********************************************************************
function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.c,v 1.13 2000/01/05 03:10:56 xiphmont Exp $
+ last mod: $Id: envelope.c,v 1.14 2000/01/22 13:28:18 xiphmont Exp $
Preecho calculation.
static void _ve_deltas(double *deltas,double *pcm,int n,double *window,
int winsize,mdct_lookup *m){
int i,j;
- double *out=alloca(sizeof(double)*winsize/2);
+ double *out=alloca(sizeof(double)*winsize);
for(j=0;j<n;j++){
double acc=0.;
-
- mdct_forward(m,pcm+j*winsize,out,window);
+
+ memcpy(out,pcm+j*winsize,winsize);
+ for(i=0;i<winsize;i++)
+ out[i]*=window[i];
+
+ mdct_forward(m,out,out);
for(i=winsize/10;i<winsize/2;i++)
acc+=fabs(out[i]);
if(deltas[j]<acc)deltas[j]=acc;
********************************************************************
function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.1 2000/01/20 04:42:55 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.2 2000/01/22 13:28:19 xiphmont Exp $
********************************************************************/
#include "vorbis/codec.h"
#include "bitwise.h"
#include "registry.h"
-#include "floor0.h"
-extern _vi_info_floor *_vorbis_floor0_dup(_vi_info_floor *source){
+static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
+ vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
+ int j;
+ _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(j=0;j<d->stages;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;j<d->stages;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;i<d->stages;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<d.stages;i++){
- d.books[i]=_oggpack_read(opb,8);
- if(d.books[i]<0 || d.books[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
+};
+
+
+++ /dev/null
-/********************************************************************
- * *
- * 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 <monty@xiph.org> 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);
-
********************************************************************
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 $
********************************************************************/
#include "bitwise.h"
#include "bookinternal.h"
#include "registry.h"
+#include "window.h"
#include "psy.h"
/* helpers */
}
/* 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);
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
for(i=0;i<source->comments;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;i<source->modes;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;i<source->times;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;i<source->floors;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;i<source->residues;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){
}
}
- /* dup psychoacoustics (if any) */
- if(source->psys){
- dest->psylist=calloc(source->psys,sizeof(void *));
- for(i=0;i<source->psys;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){
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;
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;
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 **********************************************/
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;
_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;
_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;
********************************************************************
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 $
********************************************************************/
#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);
********************************************************************
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 $
********************************************************************/
#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));
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){
}
}
-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);
/* 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);
for(i=0;i<vi->channels;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;
}
#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;i<vi->channels;i++){
+ double *pcm=vb->pcm[i];
+ for(j=0;j<n;j++)
+ pcm[j]*=window[j];
+ }
+ }
+
/* time-domain post-window: NONE IMPLEMENTED */
/* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
-
- /* perform psychoacoustics; takes PCM vector; returns transform floor
- and resolution floor, modifies PCM vector */
-
- /* perform floor encoding; takes transform floor, returns decoded floor*/
-
- /* perform residue encoding with residue mapping */
-
-
-
- psy_lookup *vp=&vb->vd->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;i<vi->channels;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;i<vi->channels;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;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[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;j<n/2;j++)
- fprintf(out,"%g\n",floor[j]);
- fclose(out);
- }
-#endif
-
- /* 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);
-
- /* 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;j<vl->m;j++)
- fprintf(out,"%g\n",lpc[j]);
- fclose(out);
-
- sprintf(buffer,"Alsp%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lsp[j]);
- fclose(out);
-
- sprintf(buffer,"Amask%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",curve[j]);
- fclose(out);
-
- sprintf(buffer,"Ares%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[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;i<vi->channels;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;i<n/2;i++){
- fprintf(out," 0. 0.\n");
- fprintf(out,"%g %g\n",C[i],D[i]);
- fprintf(out,"\n");
- }
- fclose(out);
-
- sprintf(buffer,"L%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",C[i]);
- }
- fclose(out);
- sprintf(buffer,"R%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",D[i]);
- }
- fclose(out);
-
- }
-
- _vp_balance_apply(D,C,balance_v,balance_amp,vbal,1);
-
- {
- FILE *out;
- char buffer[80];
-
- sprintf(buffer,"bal%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out," 0. 0.\n");
- fprintf(out,"%g %g\n",C[i],D[i]);
- fprintf(out,"\n");
- }
- fclose(out);
- sprintf(buffer,"C%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",C[i]);
- }
- fclose(out);
- sprintf(buffer,"D%d.m",frameno);
- out=fopen(buffer,"w+");
- for(i=0;i<n/2;i++){
- fprintf(out,"%g\n",D[i]);
- }
- fclose(out);
-
- }
- }*/
-int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
- double *window;
- vorbis_dsp_state *vd=vb->vd;
- 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 */
/* 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;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[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;j<n/2;j++)
- fprintf(out,"%g\n",curve[j]);
- fclose(out);
-
- sprintf(buffer,"Slsp%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;j++)
- fprintf(out,"%g\n",lsp[j]);
- fclose(out);
-
- sprintf(buffer,"Slpc%d.m",vb->sequence);
- out=fopen(buffer,"w+");
- for(j=0;j<vl->m;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;j<n/2;j++)
- fprintf(out,"%g\n",vb->pcm[i][j]);
- fclose(out);
- }
-#endif
/* MDCT->time */
+++ /dev/null
-/********************************************************************
- * *
- * 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 <monty@xiph.org> 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 *);
-
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
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));
for(i=0;i<n8;i+=2){
A-=2;
- tempA= in[in1+2]*window[in1+2] + in[in2]*window[in2];
- tempB= in[in1]*window[in1] + in[in2+2]*window[in2+2];
+ tempA= in[in1+2] + in[in2];
+ tempB= in[in1] + in[in2+2];
in1 -=4;in2 +=4;
x[i]= tempB*A[1] + tempA*A[0];
x[i+1]= tempB*A[0] - tempA*A[1];
for(;i<n2-n8;i+=2){
A-=2;
- tempA= in[in1+2]*window[in1+2] - in[in2]*window[in2];
- tempB= in[in1]*window[in1] - in[in2+2]*window[in2+2];
+ tempA= in[in1+2] - in[in2];
+ tempB= in[in1] - in[in2+2];
in1 -=4;in2 +=4;
x[i]= tempB*A[1] + tempA*A[0];
x[i+1]= tempB*A[0] - tempA*A[1];
for(;i<n2;i+=2){
A-=2;
- tempA= -in[in1+2]*window[in1+2] - in[in2]*window[in2];
- tempB= -in[in1]*window[in1] - in[in2+2]*window[in2+2];
+ tempA= -in[in1+2] - in[in2];
+ tempB= -in[in1] - in[in2+2];
in1 -=4;in2 +=4;
x[i]= tempB*A[1] + tempA*A[0];
x[i+1]= tempB*A[0] - tempA*A[1];
}
}
-void mdct_backward(mdct_lookup *init, double *in, double *out, double *window){
+void mdct_backward(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));
int n8=n>>3;
int i;
- /* window + rotate + step 1 */
+ /* rotate + step 1 */
{
double *inO=in+1;
double *xO= x;
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--;
-
********************************************************************
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 $
********************************************************************/
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
* *
********************************************************************
- 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
********************************************************************
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 $
********************************************************************/
/* 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;
curoc=newoc;
}
troll=fromdB(roll);
- if(m[i]<troll)m[i]=troll;
+ if(mask[i]<troll)mask[i]=troll;
+ if(floor[i]<troll)floor[i]=troll;
}
curmask=todB(f[n-1])+p->maskthresh[n-1];
curoc=newoc;
}
troll=fromdB(roll);
- if(m[i]<troll)m[i]=troll;
+ if(mask[i]<troll)mask[i]=troll;
+ if(floor[i]<troll)floor[i]=troll;
}
}
********************************************************************
function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.5 2000/01/20 04:43:03 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.6 2000/01/22 13:28:28 xiphmont Exp $
********************************************************************/
#ifndef _V_PSY_H_
#define _V_PSY_H_
-typedef struct vorbis_info_psy{
- double maskthresh[MAX_BARK];
- double lrolldB;
- double hrolldB;
-} vorbis_info_psy;
-
typedef struct {
int n;
struct vorbis_info_psy *vi;
} psy_lookup;
-
extern void _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate);
extern void _vp_psy_clear(psy_lookup *p);
extern void *_vi_psy_dup(void *source);
extern void _vi_psy_free(void *i);
-extern void _vp_noise_floor(psy_lookup *p, double *f, double *m);
-extern void _vp_mask_floor(psy_lookup *p,double *f, double *m);
+extern void _vp_mask_floor(psy_lookup *p,double *pcm,
+ double *mask,double *floor);
#endif
********************************************************************
function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.c,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+ last mod: $Id: registry.c,v 1.2 2000/01/22 13:28:29 xiphmont Exp $
********************************************************************/
#include "vorbis/codec.h"
-#include "time0.h"
-#include "floor0.h"
-#include "res0.h"
-#include "mapping0.h"
#include "registry.h"
-/* time backend registry */
-void *(*vorbis_time_dup_P[])(void *)={
- &_vorbis_time0_dup,
-};
-
-void (*vorbis_time_free_P[])(void *)={
- &_vorbis_time0_free,
-};
+/* seems like major overkill now; the backend numbers will grow into
+ the infrastructure soon enough */
-void (*vorbis_time_pack_P[])(oggpack_buffer *,void *)={
- &_vorbis_time0_pack,
-};
+extern vorbis_func_time time0_exportbundle;
+extern vorbis_func_floor floor0_exportbundle;
+extern vorbis_func_residue residue0_exportbundle;
+extern vorbis_func_mapping mapping0_exportbundle;
-void *(*vorbis_time_unpack_P[])(oggpack_buffer *)={
- &_vorbis_time0_unpack,
+vorbis_func_time *_time_P[]={
+ &time0_exportbundle,
};
-/* floor backend registry */
-void *(*vorbis_floor_dup_P[])(void *)={
- &_vorbis_floor0_dup,
+vorbis_func_floor *_floor_P[]={
+ &floor0_exportbundle,
};
-void (*vorbis_floor_free_P[])(void *)={
- &_vorbis_floor0_free,
+vorbis_func_residue *_residue_P[]={
+ &residue0_exportbundle,
};
-void (*vorbis_floor_pack_P[])(oggpack_buffer *,void *)={
- &_vorbis_floor0_pack,
+vorbis_func_mapping *_mapping_P[]={
+ &mapping0_exportbundle,
};
-void *(*vorbis_floor_unpack_P[])(oggpack_buffer *)={
- &_vorbis_floor0_unpack,
-};
-
-/* residue backend registry */
-void *(*vorbis_res_dup_P[])(void *)={
- &_vorbis_res0_dup,
-};
-
-void (*vorbis_res_free_P[])(void *)={
- &_vorbis_res0_free,
-};
-
-void (*vorbis_res_pack_P[])(oggpack_buffer *,void *)={
- &_vorbis_res0_pack,
-};
-
-void *(*vorbis_res_unpack_P[])(oggpack_buffer *)={
- &_vorbis_res0_unpack,
-};
-
-/* channel mapping registry */
-void *(*vorbis_map_dup_P[])(void *)={
- &_vorbis_map0_dup,
-};
-
-void (*vorbis_map_free_P[])(void *)={
- &_vorbis_map0_free,
-};
-
-void (*vorbis_map_pack_P[])(oggpack_buffer *,void *)={
- &_vorbis_map0_pack,
-};
-
-void *(*vorbis_map_unpack_P[])(oggpack_buffer *)={
- &_vorbis_map0_unpack,
-};
-
-void *(*vorbis_map_analysis_P[])(vorbis_block *vb,void *,ogg_packet *)={
- &_vorbis_map0_analysis,
-};
-
-void *(*vorbis_map_synthesis_P[])(vorbis_block *vb,void *,ogg_packet *)={
- &_vorbis_map0_synthesis,
-};
********************************************************************
function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.h,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+ last mod: $Id: registry.h,v 1.2 2000/01/22 13:28:30 xiphmont Exp $
********************************************************************/
#ifndef _V_REG_H_
#define _V_REG_H_
-typedef void _vi_info_time;
-typedef void _vi_info_floor;
-typedef void _vi_info_res;
-typedef void _vi_info_map;
-
+#define VI_TRANSFORMB 1
+#define VI_WINDOWB 1
#define VI_TIMEB 1
-extern _vi_info_time *(*vorbis_time_dup_P[]) (_vi_info_time *);
-extern void (*vorbis_time_free_P[]) (_vi_info_time *);
-extern void (*vorbis_time_pack_P[]) (oggpack_buffer *,
- _vi_info_time *);
-extern _vi_info_time *(*vorbis_time_unpack_P[]) (vorbis_info *,
- oggpack_buffer *);
-
#define VI_FLOORB 1
-extern _vi_info_floor *(*vorbis_floor_dup_P[]) (_vi_info_floor *);
-extern void (*vorbis_floor_free_P[]) (_vi_info_floor *);
-extern void (*vorbis_floor_pack_P[]) (oggpack_buffer *,
- _vi_info_floor*);
-extern _vi_info_floor *(*vorbis_floor_unpack_P[])(vorbis_info *,
- oggpack_buffer *);
-
#define VI_RESB 1
-extern _vi_info_res *(*vorbis_res_dup_P[]) (_vi_info_res *);
-extern void (*vorbis_res_free_P[]) (_vi_info_res *);
-extern void (*vorbis_res_pack_P[]) (oggpack_buffer *,
- _vi_info_res *);
-extern _vi_info_res *(*vorbis_res_unpack_P[]) (vorbis_info *,
- oggpack_buffer *);
-
#define VI_MAPB 1
-extern _vi_info_map *(*vorbis_map_dup_P[]) (vorbis_info *,
- _vi_info_map *);
-extern void (*vorbis_map_free_P[]) (_vi_info_map *);
-extern void (*vorbis_map_pack_P[]) (vorbis_info *,
- oggpack_buffer *,
- _vi_info_map *);
-extern _vi_info_map *(*vorbis_map_unpack_P[]) (vorbis_info *,
- oggpack_buffer *);
-extern int (*vorbis_map_analysis_P[]) (vorbis_block *vb,_vi_info_map *,
- ogg_packet *);
-extern int (*vorbis_map_synthesis_P[])(vorbis_block *vb,_vi_info_map *,
- ogg_packet *);
+extern vorbis_func_time *_time_P[];
+extern vorbis_func_floor *_floor_P[];
+extern vorbis_func_residue *_residue_P[];
+extern vorbis_func_mapping *_mapping_P[];
#endif
+++ /dev/null
-/********************************************************************
- * *
- * 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 <monty@xiph.org> 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);
********************************************************************
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 $
********************************************************************/
#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);
********************************************************************
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 $
********************************************************************/
#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);
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;i<vi->channels;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]));
}
********************************************************************
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 $
********************************************************************/
#include <string.h>
#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
+};
********************************************************************
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 $
********************************************************************/
#include <math.h>
#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<left;i++){
- double x=(i+.5)/left*M_PI/2.;
- x=sin(x);
- x*=x;
- x*=M_PI/2.;
- x=sin(x);
- ret[i+leftbegin]=x;
- }
- for(i=leftbegin+left;i<rightbegin;i++)
- ret[i]=1.;
-
- for(i=0;i<right;i++){
- double x=(right-i-.5)/right*M_PI/2.;
- x=sin(x);
- x*=x;
- x*=M_PI/2.;
- x=sin(x);
- ret[i+rightbegin]=x;
+ switch(type){
+ case 0:
+ /* The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi) */
+ {
+ int leftbegin=window/4-left/2;
+ int rightbegin=window-window/4-right/2;
+ int i;
+
+ for(i=0;i<left;i++){
+ double x=(i+.5)/left*M_PI/2.;
+ x=sin(x);
+ x*=x;
+ x*=M_PI/2.;
+ x=sin(x);
+ ret[i+leftbegin]=x;
+ }
+
+ for(i=leftbegin+left;i<rightbegin;i++)
+ ret[i]=1.;
+
+ for(i=0;i<right;i++){
+ double x=(right-i-.5)/right*M_PI/2.;
+ x=sin(x);
+ x*=x;
+ x*=M_PI/2.;
+ x=sin(x);
+ ret[i+rightbegin]=x;
+ }
+ }
+ default:
+ free(ret);
+ return(NULL);
}
-
return(ret);
}
********************************************************************
function: window functions
- last mod: $Id: window.h,v 1.2 1999/12/30 07:26:56 xiphmont Exp $
+ last mod: $Id: window.h,v 1.3 2000/01/22 13:28:37 xiphmont Exp $
********************************************************************/
#ifndef _V_WINDOW_
#define _V_WINDOW_
-extern double *_vorbis_window(int window,int left,int right);
+#define VI_WINDOWB 1
+extern double *_vorbis_window(int type,int window,int left,int right);
#endif