# vorbis makefile configured for use with gcc on any platform
-# $Id: Makefile.in,v 1.3 2000/01/22 13:28:07 xiphmont Exp $
+# $Id: Makefile.in,v 1.4 2000/01/28 09:04:57 xiphmont Exp $
###############################################################################
# #
LIBS=@LIBS@ -lm
HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \
- ../include/vorbis/internal.h ../include/vorbis/backend.h \
+ ../include/vorbis/internal.h ../include/vorbis/backends.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 encoder
- last mod: $Id: encoder_example.c,v 1.4 2000/01/22 13:28:09 xiphmont Exp $
+ last mod: $Id: encoder_example.c,v 1.5 2000/01/28 09:04:58 xiphmont Exp $
********************************************************************/
vorbis_info vi; /* struct that stores all the static vorbis bitstream
settings */
+ vorbis_comment vc; /* struct that stores all the user comments */
+ settings */
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
vorbis_block vb; /* local working space for packet->PCM decode */
function: libvorbis backend and mapping structures; needed for
static mode headers
- last mod: $Id: backends.h,v 1.2 2000/01/22 13:28:10 xiphmont Exp $
+ last mod: $Id: backends.h,v 1.3 2000/01/28 09:04:59 xiphmont Exp $
********************************************************************/
int (*forward) (struct vorbis_block *,vorbis_look_floor *,
double *,double *);
int (*inverse) (struct vorbis_block *,vorbis_look_floor *,
- double *,double *);
+ double *);
} vorbis_func_floor;
typedef struct{
void (*free_info) (vorbis_info_residue *);
void (*free_look) (vorbis_look_residue *);
int (*forward) (struct vorbis_block *,vorbis_look_residue *,
- double *,double *);
+ double **,int **,int);
int (*inverse) (struct vorbis_block *,vorbis_look_residue *,
- double *,double *);
+ double **,int);
} vorbis_func_residue;
typedef struct vorbis_info_residue0{
/* Mapping backend generic *****************************************/
typedef struct{
- void (*pack) (vorbis_info_mapping *,oggpack_buffer *);
+ void (*pack) (vorbis_info *,vorbis_info_mapping *,
+ oggpack_buffer *);
vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
vorbis_look_mapping *(*look) (vorbis_info *,vorbis_info_mode *,
vorbis_info_mapping *);
1694, 1694
};
-static codebook _vq_book_lsp20_0 = {
+static static_codebook _vq_book_lsp20_0 = {
4, 256, 4152003, 2812515, 8, 1,
_vq_quantlist_lsp20_0,
_vq_lengthlist_lsp20_0,
2743, 2743
};
-static codebook _vq_book_lsp32_0 = {
+static static_codebook _vq_book_lsp32_0 = {
4, 256, 4089638, 2558033, 8, 1,
_vq_quantlist_lsp32_0,
_vq_lengthlist_lsp32_0,
********************************************************************
function: codebook types
- last mod: $Id: codebook.h,v 1.3 2000/01/22 10:40:36 xiphmont Exp $
+ last mod: $Id: codebook.h,v 1.4 2000/01/28 09:05:00 xiphmont Exp $
********************************************************************/
typedef struct codebook{
long dim; /* codebook dimensions (elements per vector) */
long entries; /* codebook entries */
- static_codebook *c;
+ const static_codebook *c;
double *valuelist; /* list of dim*entries actual entry values */
long *codelist; /* list of bitstream codewords for each entry */
********************************************************************
function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.5 2000/01/22 13:28:11 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.6 2000/01/28 09:05:01 xiphmont Exp $
********************************************************************/
/* the comments are not part of vorbis_info so that vorbis_info can be
static storage */
-typedef struct vorbis_comments{
+typedef struct vorbis_comment{
/* unlimited user comment fields. libvorbis writes 'libvorbis'
whatever vendor is set to in encode */
char **user_comments;
int comments;
char *vendor;
-} vorbis_comments;
+} vorbis_comment;
/* libvorbis encodes in two abstraction layers; first we perform DSP
/* Vorbis PRIMITIVES: general ***************************************/
-extern int vorbis_info_init(vorbis_info *vi,vorbis_comments *vc);
-extern int vorbis_comment_init(vorbis_comments *vc);
-extern int vorbis_comment_add(vorbis_comments *vc, char *comment);
-extern int vorbis_comment_clear(vorbis_comments *vc);
+extern void vorbis_info_init(vorbis_info *vi);
+extern void vorbis_info_clear(vorbis_info *vi);
+extern void vorbis_comment_init(vorbis_comment *vc);
+extern void vorbis_comment_add(vorbis_comment *vc, char *comment);
+extern void vorbis_comment_clear(vorbis_comment *vc);
extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
extern int vorbis_block_clear(vorbis_block *vb);
extern void vorbis_dsp_clear(vorbis_dsp_state *v);
/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
+
extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
extern int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
ogg_packet *op,
ogg_packet *op_comm,
ogg_packet *op_code);
extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op);
/* Vorbis PRIMITIVES: synthesis layer *******************************/
-extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comments *vc,
+extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
ogg_packet *op);
extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.h,v 1.1 2000/01/05 03:10:47 xiphmont Exp $
+ last mod: $Id: vorbisfile.h,v 1.2 2000/01/28 09:05:02 xiphmont Exp $
********************************************************************/
long *serialnos;
int64_t *pcmlengths;
vorbis_info *vi;
+ vorbis_comment *vc;
/* Decoding working state local storage */
int64_t pcm_offset;
extern double ov_time_tell(OggVorbis_File *vf);
extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
+extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
int bigendianp,int word,int sgned,int *bitstream);
# vorbis makefile configured for use with gcc on any platform
-# $Id: Makefile.in,v 1.23 2000/01/22 13:28:13 xiphmont Exp $
+# $Id: Makefile.in,v 1.24 2000/01/28 09:05:05 xiphmont Exp $
###############################################################################
# #
LIBS=@LIBS@ -lm
HFILES = ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \
- ../include/vorbis/internal.h ../include/vorbis/backend.h \
+ ../include/vorbis/internal.h ../include/vorbis/backends.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\
- spectrum.o codebook.o vorbisfile.o
+ codebook.o vorbisfile.o
all:
$(MAKE) target CFLAGS="$(OPT)"
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.23 2000/01/22 13:28:15 xiphmont Exp $
+ last mod: $Id: block.c,v 1.24 2000/01/28 09:05:06 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
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){
-
+ int i;
_vds_shared_init(v,vi);
+ /* finish the codebooks */
+ v->fullbooks=calloc(vi->books,sizeof(codebook));
+ for(i=0;i<vi->books;i++)
+ vorbis_book_init_encode(v->fullbooks+i,vi->book_param[i]);
+
/* Initialize the envelope multiplier storage */
v->envelope_storage=v->pcm_storage/vi->envelopesa;
}
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
+ int i;
_vds_shared_init(v,vi);
+ /* finish the codebooks */
+ v->fullbooks=calloc(vi->books,sizeof(codebook));
+ for(i=0;i<vi->books;i++)
+ vorbis_book_init_decode(v->fullbooks+i,vi->book_param[i]);
+
/* Adjust centerW to allow an easier mechanism for determining output */
v->pcm_returned=v->centerW;
v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
********************************************************************
function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: bookinternal.h,v 1.4 2000/01/22 13:28:16 xiphmont Exp $
+ last mod: $Id: bookinternal.h,v 1.5 2000/01/28 09:05:07 xiphmont Exp $
********************************************************************/
#include "vorbis/codebook.h"
#include "bitwise.h"
-extern void vorbis_book_finish(codebook *dest,const static_codebook *source);
+extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b);
+extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c);
+extern void vorbis_staticbook_clear(static_codebook *b);
+
+extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source);
+extern int vorbis_book_init_decode(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);
extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b);
extern int vorbis_book_encodev(codebook *book, double *a, oggpack_buffer *b);
********************************************************************
function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: codebook.c,v 1.3 2000/01/22 13:28:17 xiphmont Exp $
+ last mod: $Id: codebook.c,v 1.4 2000/01/28 09:05:08 xiphmont Exp $
********************************************************************/
return(ret);
}
-static long _float24_pack(double val){
- int sign=0;
- long exp;
- long mant;
- if(val<0){
- sign=0x800000;
- val= -val;
- }
- exp= floor(log(val)/log(2));
- mant=rint(ldexp(val,17-exp));
- exp=(exp+VQ_FEXP_BIAS)<<18;
-
- return(sign|exp|mant);
-}
+/* code that packs the 24 bit float can be found in vq/bookutil.c */
static double _float24_unpack(long val){
double mant=val&0x3ffff;
return(r);
}
+/* build the decode helper tree from the codewords */
+decode_aux *_make_decode_tree(codebook *c){
+ const static_codebook *s=c->c;
+ long top=0,i,j;
+ decode_aux *t=malloc(sizeof(decode_aux));
+ long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long));
+ long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long));
+ long *codelist=_make_words(s->lengthlist,s->entries);
+
+ if(codelist==NULL)return(NULL);
+ t->aux=c->entries*2;
+
+ for(i=0;i<c->entries;i++){
+ long ptr=0;
+ for(j=0;j<s->lengthlist[i]-1;j++){
+ int bit=(codelist[i]>>j)&1;
+ if(!bit){
+ if(!ptr0[ptr])
+ ptr0[ptr]= ++top;
+ ptr=ptr0[ptr];
+ }else{
+ if(!ptr1[ptr])
+ ptr1[ptr]= ++top;
+ ptr=ptr1[ptr];
+ }
+ }
+ if(!((codelist[i]>>j)&1))
+ ptr0[ptr]=-i;
+ else
+ ptr1[ptr]=-i;
+ }
+ free(codelist);
+ return(t);
+}
+
/* unpack the quantized list of values for encode/decode ***********/
-static double *_book_unquantize(static_codebook *b){
+static double *_book_unquantize(const static_codebook *b){
long j,k;
double mindel=_float24_unpack(b->q_min);
double delta=_float24_unpack(b->q_delta);
return(r);
}
+void vorbis_staticbook_clear(static_codebook *b){
+ if(b->quantlist)free(b->quantlist);
+ if(b->lengthlist)free(b->lengthlist);
+ if(b->encode_tree){
+ free(b->encode_tree->ptr0);
+ free(b->encode_tree->ptr1);
+ free(b->encode_tree->p);
+ free(b->encode_tree->q);
+ memset(b->encode_tree,0,sizeof(encode_aux));
+ free(b->encode_tree);
+ }
+ memset(b,0,sizeof(static_codebook));
+}
+
void vorbis_book_clear(codebook *b){
- /* static book is not cleared. It exists only in encode */
+ /* static book is not cleared; we're likely called on the lookup and
+ the static codebook belongs to the info struct */
if(b->decode_tree){
free(b->decode_tree->ptr0);
free(b->decode_tree->ptr1);
memset(b,0,sizeof(codebook));
}
-int vorbis_book_finish(codebook *c, static_codebook *s){
+int vorbis_book_init_encode(codebook *c,const static_codebook *s){
+ memset(c,0,sizeof(codebook));
+ c->c=s;
+ c->entries=s->entries;
+ c->dim=s->dim;
+ c->codelist=_make_words(s->lengthlist,s->entries);
+ c->valuelist=_book_unquantize(s);
+ return(0);
+}
+
+int vorbis_book_init_decode(codebook *c,const static_codebook *s){
memset(c,0,sizeof(codebook));
c->c=s;
- c->elements=s->elements;
+ c->entries=s->entries;
c->dim=s->dim;
- c->codelist=_make_words(c->lengthlist,c->entries);
- c->valuelist=_book_unquantize(c);
+ c->valuelist=_book_unquantize(s);
+ c->decode_tree=_make_decode_tree(c);
+ if(c->decode_tree==NULL)goto err_out;
return(0);
+ err_out:
+ vorbis_book_clear(c);
+ return(-1);
}
/* packs the given codebook into the bitstream **************************/
-int vorbis_book_pack(static_codebook *c,oggpack_buffer *opb){
+int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
long i,j;
int ordered=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 *opb,codebook *c){
+int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
long i,j;
- long *lengthlist=NULL;
- long *codelist=NULL;
- static codebook s;
- memset(c,0,sizeof(codebook));
- memset(&s,0,sizeof(s));
+ memset(s,0,sizeof(static_codebook));
/* make sure alignment is correct */
if(_oggpack_read(opb,24)!=0x564342)goto _eofout;
/* first the basic parameters */
- c->dim=_oggpack_read(opb,16);
- c->entries=_oggpack_read(opb,24);
- if(c->entries==-1)goto _eofout;
+ s->dim=_oggpack_read(opb,16);
+ s->entries=_oggpack_read(opb,24);
+ if(s->entries==-1)goto _eofout;
/* codeword ordering.... length ordered or unordered? */
switch(_oggpack_read(opb,1)){
case 0:
/* unordered */
- lengthlist=malloc(sizeof(long)*c->entries);
- for(i=0;i<c->entries;i++){
+ s->lengthlist=malloc(sizeof(long)*s->entries);
+ for(i=0;i<s->entries;i++){
long num=_oggpack_read(opb,5);
if(num==-1)goto _eofout;
- lengthlist[i]=num+1;
+ s->lengthlist[i]=num+1;
}
-
+
break;
case 1:
/* ordered */
{
long length=_oggpack_read(opb,5)+1;
- lengthlist=malloc(sizeof(long)*c->entries);
-
- for(i=0;i<c->entries;){
- long num=_oggpack_read(opb,ilog(c->entries-i));
+ s->lengthlist=malloc(sizeof(long)*s->entries);
+
+ for(i=0;i<s->entries;){
+ long num=_oggpack_read(opb,ilog(s->entries-i));
if(num==-1)goto _eofout;
for(j=0;j<num;j++,i++)
- lengthlist[i]=length;
+ s->lengthlist[i]=length;
length++;
}
}
return(-1);
}
- /* now we generate the codewords for the given lengths */
- codelist=_make_words(c->lengthlist,c->entries);
- if(codelist==NULL)goto _errout;
-
- /* ...and the decode helper tree from the codewords */
- {
- long top=0;
- decode_aux *t=c->decode_tree=malloc(sizeof(decode_aux));
- long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long));
- long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long));
- t->aux=c->entries*2;
-
- for(i=0;i<c->entries;i++){
- long ptr=0;
- for(j=0;j<lengthlist[i]-1;j++){
- int bit=(codelist[i]>>j)&1;
- if(!bit){
- if(!ptr0[ptr])
- ptr0[ptr]= ++top;
- ptr=ptr0[ptr];
- }else{
- if(!ptr1[ptr])
- ptr1[ptr]= ++top;
- ptr=ptr1[ptr];
- }
- }
- if(!((codelist[i]>>j)&1))
- ptr0[ptr]=-i;
- else
- ptr1[ptr]=-i;
- }
- }
- /* no longer needed */
- free(lengthlist);
- free(codelist);
-
/* Do we have a mapping to unpack? */
if(_oggpack_read(opb,1)){
/* values that define the dequantization */
- 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;
+ 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);
/* quantized values */
- s.quantlist=malloc(sizeof(double)*c->entries*c->dim);
- for(i=0;i<c->entries*c->dim;i++)
- 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));
+ s->quantlist=malloc(sizeof(double)*s->entries*s->dim);
+ for(i=0;i<s->entries*s->dim;i++)
+ s->quantlist[i]=_oggpack_read(opb,s->q_quant);
+ if(s->quantlist[i-1]==-1)goto _eofout;
}
/* all set */
_errout:
_eofout:
- if(lengthlist)free(lengthlist);
- if(s.quantlist)free(s.quantlist);
- if(codelist)free(codelist);
- vorbis_book_clear(c);
- return(-1);
-
+ vorbis_staticbook_clear(s);
+ return(-1);
}
/* returns the number of bits ***************************************/
while(testlist[ptr]){
codebook c;
+ static_codebook s;
double *qv=alloca(sizeof(double)*TESTSIZE);
double *iv=alloca(sizeof(double)*TESTSIZE);
memcpy(qv,testvec[ptr],sizeof(double)*TESTSIZE);
/* pack the codebook, write the testvector */
_oggpack_reset(&write);
- vorbis_book_finish(&c,testlist[ptr]); /* get it into memory we can write */
- vorbis_book_pack(&c,&write);
+ vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory
+ we can write */
+ vorbis_book_pack(testlist[ptr],&write);
fprintf(stderr,"Codebook size %ld bytes... ",_oggpack_bytes(&write));
for(i=0;i<TESTSIZE;i+=TESTDIM)
vorbis_book_encodev(&c,qv+i,&write);
/* transfer the write data to a read buffer and unpack/read */
_oggpack_readinit(&read,_oggpack_buffer(&write),_oggpack_bytes(&write));
- if(vorbis_book_unpack(&read,&c)){
+ if(vorbis_book_unpack(&read,&s)){
fprintf(stderr,"Error unpacking codebook.\n");
exit(1);
}
+ if(vorbis_book_init_decode(&c,&s)){
+ fprintf(stderr,"Error initializing codebook.\n");
+ exit(1);
+ }
+
for(i=0;i<TESTSIZE;i+=TESTDIM)
if(vorbis_book_decodev(&c,iv+i,&read)){
fprintf(stderr,"Error reading codebook test data (EOP).\n");
********************************************************************
function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.2 2000/01/22 13:28:19 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.3 2000/01/28 09:05:09 xiphmont Exp $
********************************************************************/
#include "bitwise.h"
#include "registry.h"
+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));
+ }
+}
+static void free_look(vorbis_look_floor *i){
+}
+
static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
int j;
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));
- }
-}
-static void free_look(vorbis_look_floor *i){
-}
-static void forward(vorbis_block *vb,vorbis_look_floor *i,
+static int forward(vorbis_block *vb,vorbis_look_floor *i,
double *in,double *out){
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){
+static int inverse(vorbis_block *vb,vorbis_look_floor *i,
+ double *buf){
return(0);
}
********************************************************************
function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.17 2000/01/22 13:28:21 xiphmont Exp $
+ last mod: $Id: info.c,v 1.18 2000/01/28 09:05:10 xiphmont Exp $
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include "vorbis/codec.h"
+#include "vorbis/backends.h"
#include "bitwise.h"
#include "bookinternal.h"
#include "registry.h"
#include "psy.h"
/* helpers */
-
static int ilog2(unsigned int v){
int ret=0;
while(v>1){
}
}
-/* convenience functions for the interface */
-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);
- vi->comments++;
- vi->user_comments[vi->comments]=NULL;
- return(0);
+void vorbis_comment_init(vorbis_comment *vc){
+ memset(vc,0,sizeof(vorbis_comment));
}
-/* 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
- includes a number of modes in static storage as headers. To
- allocate a copy, run it through vorbis_info_dup */
-
-/* note that due to codebook size, codebooks are not fully duplicated.
- The info structure (aside from the embedded codebook elements) will
- be fully dupped */
-
-int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){
- int i;
- memcpy(dest,source,sizeof(vorbis_info));
-
- /* also dup individual pieces that need to be allocated */
- /* dup user comments (unlikely to have any, but for completeness */
- if(source->comments>0){
- dest->user_comments=calloc(source->comments+1,sizeof(char *));
- for(i=0;i<source->comments;i++)
- dest->user_comments[i]=strdup(source->user_comments[i]);
- }
- dest->vendor=NULL;
-
- /* modes, maps, times, floors, residues, psychoacoustics are not
- dupped; the pointer is just replicated by the above copy */
-
- /* dup (partially) books */
- if(source->books){
- dest->booklist=malloc(source->books*sizeof(codebook *));
- for(i=0;i<source->books;i++){
- dest->booklist[i]=calloc(1,sizeof(codebook));
- vorbis_book_dup(dest->booklist[i],source->booklist[i]);
- }
- }
-
- return(0);
-err_out:
- vorbis_info_clear(dest);
- return(-1);
+void vorbis_comment_add(vorbis_comment *vc,char *comment){
+ vc->user_comments=realloc(vc->user_comments,
+ (vc->comments+2)*sizeof(char *));
+ vc->user_comments[vc->comments]=strdup(comment);
+ vc->comments++;
+ vc->user_comments[vc->comments]=NULL;
}
-
- memset(vi,0,sizeof(vorbis_info));
-}
-
-void vorbis_info_anclear(vorbis_info *vi){
- memset(vi,0,sizeof(vorbis_info));
+void vorbis_comment_clear(vorbis_comment *vc){
+ if(vc){
+ long i;
+ for(i=0;i<vc->comments;i++)
+ if(vc->user_comments[i])free(vc->user_comments[i]);
+ if(vc->user_comments)free(vc->user_comments);
+ if(vc->vendor)free(vc->vendor);
+ }
+ memset(vc,0,sizeof(vorbis_comment));
}
-
-
/* 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){
- for(i=0;i<vi->comments;i++)
- if(vi->user_comments[i])free(vi->user_comments[i]);
- free(vi->user_comments);
- }
- if(vi->vendor)free(vi->vendor);
- if(vi->windowtypes)free(vi->windowtypes);
- if(vi->transformtypes)free(vi->transformtypes);
- if(vi->modes){
- for(i=0;i<vi->modes;i++)
- if(vi->mappingtypes[i]>=0 && vi->mappingtypes[i]<VI_MAPB)
- vorbis_map_free_P[vi->mappingtypes[i]](vi->modelist[i]);
- free(vi->modelist);
- free(vi->mappingtypes);
- free(vi->blockflags);
- }
- if(vi->times){
- for(i=0;i<vi->times;i++)
- if(vi->timetypes[i]>=0 && vi->timetypes[i]<VI_TIMEB)
- vorbis_time_free_P[vi->timetypes[i]](vi->timelist[i]);
- free(vi->timelist);
- free(vi->timetypes);
- }
- if(vi->floors){
- for(i=0;i<vi->floors;i++)
- if(vi->floortypes[i]>=0 && vi->floortypes[i]<VI_FLOORB)
- vorbis_floor_free_P[vi->floortypes[i]](vi->floorlist[i]);
- free(vi->floorlist);
- free(vi->floortypes);
- }
- if(vi->residues){
- for(i=0;i<vi->residues;i++)
- if(vi->residuetypes[i]>=0 && vi->residuetypes[i]<VI_RESB)
- vorbis_res_free_P[vi->residuetypes[i]](vi->residuelist[i]);
- free(vi->residuelist);
- free(vi->residuetypes);
- }
- if(vi->books){
- for(i=0;i<vi->books;i++){
- if(vi->booklist[i]){
- vorbis_book_clear(vi->booklist[i]);
- free(vi->booklist[i]);
- }
+
+ for(i=0;i<vi->modes;i++)
+ if(vi->mode_param[i])free(vi->mode_param[i]);
+ if(vi->mode_param)free(vi->mode_param);
+
+ for(i=0;i<vi->maps;i++) /* unpack does the range checking */
+ _mapping_P[i]->free_info(vi->map_param[i]);
+ if(vi->map_param)free(vi->map_param);
+
+ for(i=0;i<vi->times;i++) /* unpack does the range checking */
+ _time_P[i]->free_info(vi->time_param[i]);
+ if(vi->time_param)free(vi->time_param);
+
+ for(i=0;i<vi->floors;i++) /* unpack does the range checking */
+ _floor_P[i]->free_info(vi->floor_param[i]);
+ if(vi->floor_param)free(vi->floor_param);
+
+ for(i=0;i<vi->residues;i++) /* unpack does the range checking */
+ _residue_P[i]->free_info(vi->residue_param[i]);
+ if(vi->residue_param)free(vi->residue_param);
+
+ /* the static codebooks *are* freed if you call info_clear, because
+ decode side does alloc a 'static' codebook. Calling clear on the
+ full codebook does not clear the static codebook (that's our
+ responsibility) */
+ for(i=0;i<vi->books;i++){
+ /* just in case the decoder pre-cleared to save space */
+ if(vi->book_param[i]){
+ vorbis_staticbook_clear(vi->book_param[i]);
+ free(vi->book_param[i]);
}
- free(vi->booklist);
}
- if(vi->psys){
- for(i=0;i<vi->psys;i++)
- _vi_psy_free(vi->psylist[i]);
- free(vi->psylist);
- }
-
- if(vi->header)free(vi->header);
- if(vi->header1)free(vi->header1);
- if(vi->header2)free(vi->header2);
+ if(vi->book_param)free(vi->book_param);
+ for(i=0;i<vi->psys;i++)
+ _vi_psy_free(vi->psy_param[i]);
+ if(vi->psy_param)free(vi->psy_param);
+
memset(vi,0,sizeof(vorbis_info));
}
return(-1);
}
-static int _vorbis_unpack_comments(vorbis_info *vi,oggpack_buffer *opb){
+static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
int i;
int vendorlen=_oggpack_read(opb,32);
if(vendorlen<0)goto err_out;
- vi->vendor=calloc(vendorlen+1,1);
- _v_readstring(opb,vi->vendor,vendorlen);
- vi->comments=_oggpack_read(opb,32);
- if(vi->comments<0)goto err_out;
- vi->user_comments=calloc(vi->comments+1,sizeof(char **));
+ vc->vendor=calloc(vendorlen+1,1);
+ _v_readstring(opb,vc->vendor,vendorlen);
+ vc->comments=_oggpack_read(opb,32);
+ if(vc->comments<0)goto err_out;
+ vc->user_comments=calloc(vc->comments+1,sizeof(char **));
- for(i=0;i<vi->comments;i++){
+ for(i=0;i<vc->comments;i++){
int len=_oggpack_read(opb,32);
if(len<0)goto err_out;
- vi->user_comments[i]=calloc(len+1,1);
- _v_readstring(opb,vi->user_comments[i],len);
+ vc->user_comments[i]=calloc(len+1,1);
+ _v_readstring(opb,vc->user_comments[i],len);
}
if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);
err_out:
- vorbis_info_clear(vi);
+ vorbis_comment_clear(vc);
return(-1);
}
static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
int i;
+ /* codebooks */
+ vi->books=_oggpack_read(opb,16);
+ vi->book_param=calloc(vi->books,sizeof(static_codebook *));
+ for(i=0;i<vi->books;i++){
+ vi->book_param[i]=calloc(1,sizeof(static_codebook));
+ if(vorbis_staticbook_unpack(opb,vi->book_param[i]))goto err_out;
+ }
+
/* time backend settings */
vi->times=_oggpack_read(opb,8);
- vi->timetypes=malloc(vi->times*sizeof(int));
- vi->timelist=calloc(vi->times,sizeof(void *));
+ vi->time_type=malloc(vi->times*sizeof(int));
+ vi->time_param=calloc(vi->times,sizeof(void *));
for(i=0;i<vi->times;i++){
- vi->timetypes[i]=_oggpack_read(opb,16);
- if(vi->timetypes[i]<0 || vi->timetypes[i]>VI_TIMEB)goto err_out;
- vi->timelist[i]=vorbis_time_unpack_P[vi->timetypes[i]](vi,opb);
- if(!vi->timelist[i])goto err_out;
+ vi->time_type[i]=_oggpack_read(opb,16);
+ if(vi->time_type[i]<0 || vi->time_type[i]>=VI_TIMEB)goto err_out;
+ vi->time_param[i]=_time_P[vi->time_type[i]]->unpack(vi,opb);
+ if(!vi->time_param[i])goto err_out;
}
/* floor backend settings */
vi->floors=_oggpack_read(opb,8);
- vi->floortypes=malloc(vi->floors*sizeof(int));
- vi->floorlist=calloc(vi->floors,sizeof(void *));
+ vi->floor_type=malloc(vi->floors*sizeof(int));
+ vi->floor_param=calloc(vi->floors,sizeof(void *));
for(i=0;i<vi->floors;i++){
- vi->floortypes[i]=_oggpack_read(opb,16);
- if(vi->floortypes[i]<0 || vi->floortypes[i]>VI_FLOORB)goto err_out;
- vi->floorlist[i]=vorbis_floor_unpack_P[vi->floortypes[i]](vi,opb);
- if(!vi->floorlist[i])goto err_out;
+ vi->floor_type[i]=_oggpack_read(opb,16);
+ if(vi->floor_type[i]<0 || vi->floor_type[i]>=VI_FLOORB)goto err_out;
+ vi->floor_param[i]=_floor_P[vi->floor_type[i]]->unpack(vi,opb);
+ if(!vi->floor_param[i])goto err_out;
}
/* residue backend settings */
vi->residues=_oggpack_read(opb,8);
- vi->residuetypes=malloc(vi->residues*sizeof(int));
- vi->residuelist=calloc(vi->residues,sizeof(void *));
+ vi->residue_type=malloc(vi->residues*sizeof(int));
+ vi->residue_param=calloc(vi->residues,sizeof(void *));
for(i=0;i<vi->residues;i++){
- vi->residuetypes[i]=_oggpack_read(opb,16);
- if(vi->residuetypes[i]<0 || vi->residuetypes[i]>VI_RESB)goto err_out;
- vi->residuelist[i]=vorbis_res_unpack_P[vi->residuetypes[i]](vi,opb);
- if(!vi->residuelist[i])goto err_out;
+ vi->residue_type[i]=_oggpack_read(opb,16);
+ if(vi->residue_type[i]<0 || vi->residue_type[i]>=VI_RESB)goto err_out;
+ vi->residue_param[i]=_residue_P[vi->residue_type[i]]->unpack(vi,opb);
+ if(!vi->residue_param[i])goto err_out;
}
- /* codebooks */
- vi->books=_oggpack_read(opb,16);
- vi->booklist=calloc(vi->books,sizeof(codebook *));
- for(i=0;i<vi->books;i++){
- vi->booklist[i]=calloc(1,sizeof(codebook));
- if(vorbis_book_unpack(opb,vi->booklist[i]))goto err_out;
+ /* map backend settings */
+ vi->maps=_oggpack_read(opb,8);
+ vi->map_type=malloc(vi->maps*sizeof(int));
+ vi->map_param=calloc(vi->maps,sizeof(void *));
+ for(i=0;i<vi->maps;i++){
+ vi->map_type[i]=_oggpack_read(opb,16);
+ if(vi->map_type[i]<0 || vi->map_type[i]>=VI_MAPB)goto err_out;
+ vi->map_param[i]=_mapping_P[vi->map_type[i]]->unpack(vi,opb);
+ if(!vi->map_param[i])goto err_out;
}
-
- /* modes/mappings; these are loaded last in order that the mappings
- can range-check their time/floor/res/book settings */
+
+ /* mode settings */
vi->modes=_oggpack_read(opb,8);
- vi->blockflags=malloc(vi->modes*sizeof(int));
- vi->windowtypes=malloc(vi->modes*sizeof(int));
- vi->transformtypes=malloc(vi->modes*sizeof(int));
- vi->mappingtypes=malloc(vi->modes*sizeof(int));
- vi->modelist=calloc(vi->modes,sizeof(void *));
+ vi->mode_param=calloc(vi->modes,sizeof(void *));
for(i=0;i<vi->modes;i++){
- vi->blockflags[i]=_oggpack_read(opb,1);
- 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 || 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;
+ vi->mode_param[i]=calloc(1,sizeof(vorbis_info_mode));
+ vi->mode_param[i]->blockflag=_oggpack_read(opb,1);
+ vi->mode_param[i]->windowtype=_oggpack_read(opb,16);
+ vi->mode_param[i]->transformtype=_oggpack_read(opb,16);
+ vi->mode_param[i]->mapping=_oggpack_read(opb,8);
+
+ if(vi->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+ if(vi->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+ if(vi->mode_param[i]->mapping>=vi->maps)goto err_out;
}
-
+
if(_oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
return(0);
-err_out:
+ err_out:
vorbis_info_clear(vi);
return(-1);
}
with bitstream comments and a third packet that holds the
codebook. */
-int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
-
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
oggpack_buffer opb;
if(op){
return(-1);
}
- return(_vorbis_unpack_comments(vi,&opb));
+ return(_vorbis_unpack_comment(vc,&opb));
case 0x82:
- if(vi->rate==0 || vi->vendor==NULL){
+ if(vi->rate==0 || vc->vendor==NULL){
/* um... we didn;t get the initial header or comments yet */
return(-1);
}
return(0);
}
-static int _vorbis_pack_comments(oggpack_buffer *opb,vorbis_info *vi){
- char temp[]="Xiphophorus libVorbis I 20000114";
+static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+ char temp[]="Xiphophorus libVorbis I 20000121";
/* preamble */
_v_writestring(opb,"vorbis");
/* comments */
- _oggpack_write(opb,vi->comments,32);
- if(vi->comments){
+ _oggpack_write(opb,vc->comments,32);
+ if(vc->comments){
int i;
- for(i=0;i<vi->comments;i++){
- if(vi->user_comments[i]){
- _oggpack_write(opb,strlen(vi->user_comments[i]),32);
- _v_writestring(opb,vi->user_comments[i]);
+ for(i=0;i<vc->comments;i++){
+ if(vc->user_comments[i]){
+ _oggpack_write(opb,strlen(vc->user_comments[i]),32);
+ _v_writestring(opb,vc->user_comments[i]);
}else{
_oggpack_write(opb,0,32);
}
_v_writestring(opb,"vorbis");
_oggpack_write(opb,0x82,8);
+ /* books */
+ _oggpack_write(opb,vi->books,16);
+ for(i=0;i<vi->books;i++)
+ if(vorbis_staticbook_pack(vi->book_param[i],opb))goto err_out;
+
/* times */
_oggpack_write(opb,vi->times,8);
for(i=0;i<vi->times;i++){
- _oggpack_write(opb,vi->timetypes[i],16);
- vorbis_time_pack_P[vi->timetypes[i]](opb,vi->timelist[i]);
+ _oggpack_write(opb,vi->time_type[i],16);
+ _time_P[vi->time_type[i]]->pack(vi->time_param[i],opb);
}
/* floors */
_oggpack_write(opb,vi->floors,8);
for(i=0;i<vi->floors;i++){
- _oggpack_write(opb,vi->floortypes[i],16);
- vorbis_floor_pack_P[vi->floortypes[i]](opb,vi->floorlist[i]);
+ _oggpack_write(opb,vi->floor_type[i],16);
+ _floor_P[vi->floor_type[i]]->pack(vi->floor_param[i],opb);
}
/* residues */
_oggpack_write(opb,vi->residues,8);
for(i=0;i<vi->residues;i++){
- _oggpack_write(opb,vi->residuetypes[i],16);
- vorbis_res_pack_P[vi->residuetypes[i]](opb,vi->residuelist[i]);
+ _oggpack_write(opb,vi->residue_type[i],16);
+ _residue_P[vi->residue_type[i]]->pack(vi->residue_param[i],opb);
}
- /* books */
- _oggpack_write(opb,vi->books,16);
- for(i=0;i<vi->books;i++)
- if(vorbis_book_pack(vi->booklist[i],opb))goto err_out;
-
- /* mode mappings */
+ /* maps */
+ _oggpack_write(opb,vi->maps,8);
+ for(i=0;i<vi->maps;i++){
+ _oggpack_write(opb,vi->map_type[i],16);
+ _mapping_P[vi->map_type[i]]->pack(vi,vi->map_param[i],opb);
+ }
+ /* modes */
_oggpack_write(opb,vi->modes,8);
for(i=0;i<vi->modes;i++){
- _oggpack_write(opb,vi->blockflags[i],1);
- _oggpack_write(opb,vi->windowtypes[i],16);
- _oggpack_write(opb,vi->transformtypes[i],16);
- _oggpack_write(opb,vi->mappingtypes[i],16);
- vorbis_map_pack_P[vi->mappingtypes[i]](vi,opb,vi->modelist[i]);
+ _oggpack_write(opb,vi->mode_param[i]->blockflag,1);
+ _oggpack_write(opb,vi->mode_param[i]->windowtype,16);
+ _oggpack_write(opb,vi->mode_param[i]->transformtype,16);
+ _oggpack_write(opb,vi->mode_param[i]->mapping,8);
}
-
_oggpack_write(opb,1,1);
return(0);
}
int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
ogg_packet *op,
ogg_packet *op_comm,
ogg_packet *op_code){
_oggpack_reset(&opb);
_v_writestring(&opb,"vorbis");
_oggpack_write(&opb,0x81,8);
- if(_vorbis_pack_comments(&opb,vi))goto err_out;
+ if(_vorbis_pack_comment(&opb,vc))goto err_out;
if(v->header1)free(v->header1);
v->header1=malloc(_oggpack_bytes(&opb));
memset(op,0,sizeof(ogg_packet));
memset(op_comm,0,sizeof(ogg_packet));
memset(op_code,0,sizeof(ogg_packet));
+
+ if(v->header)free(v->header);
+ if(v->header1)free(v->header1);
+ if(v->header2)free(v->header2);
+ v->header=NULL;
+ v->header1=NULL;
+ v->header2=NULL;
return(-1);
}
********************************************************************
function: LPC low level routines
- last mod: $Id: lpc.c,v 1.14 2000/01/20 04:43:01 xiphmont Exp $
+ last mod: $Id: lpc.c,v 1.15 2000/01/28 09:05:11 xiphmont Exp $
********************************************************************/
#endif
}
-void vorbis_lpc_apply(double *residue,double *lpc,double amp,lpc_lookup *l){
- double *lcurve=alloca(sizeof(double)*((l->ln+l->n)*2));
- int i;
-
- if(amp==0){
- memset(residue,0,l->n*sizeof(double));
- }else{
-
- _vlpc_de_helper(lcurve,lpc,amp,l);
-
- for(i=0;i<l->ln;i++)lcurve[i]/=l->barknorm[i];
- for(i=0;i<l->n;i++)
- if(residue[i]!=0)
- residue[i]*=lcurve[l->linearmap[i]];
- }
-}
-
/* subtract or add an lpc filter to data. Vorbis doesn't actually use this. */
void vorbis_lpc_residue(double *coeff,double *prime,int m,
********************************************************************
function: LPC low level routines
- last mod: $Id: lpc.h,v 1.8 2000/01/22 13:28:22 xiphmont Exp $
+ last mod: $Id: lpc.h,v 1.9 2000/01/28 09:05:12 xiphmont Exp $
********************************************************************/
extern double vorbis_curve_to_lpc(double *curve,double *lpc,lpc_lookup *l);
extern void vorbis_lpc_to_curve(double *curve,double *lpc, double amp,
lpc_lookup *l);
-extern void vorbis_lpc_apply(double *residue,double *lpc, double amp,
- lpc_lookup *l);
/* standard lpc stuff */
extern void vorbis_lpc_residue(double *coeff,double *prime,int m,
********************************************************************
function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.2 2000/01/22 13:28:23 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.3 2000/01/28 09:05:13 xiphmont Exp $
********************************************************************/
#include <string.h>
#include <math.h>
#include "vorbis/codec.h"
+#include "vorbis/backends.h"
#include "bitwise.h"
#include "bookinternal.h"
#include "registry.h"
-#include "mapping0.h"
+#include "psy.h"
+#include "misc.h"
-_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));
+/* simplistic, wasteful way of doing this (unique lookup for each
+ mode/submapping); there should be a central repository for
+ identical lookups. That will require minor work, so I'm putting it
+ off as low priority.
- d->floorsubmap=malloc(sizeof(int)*vi->channels);
- d->residuesubmap=malloc(sizeof(int)*vi->channels);
- d->psysubmap=malloc(sizeof(int)*vi->channels);
- memcpy(d->floorsubmap,s->floorsubmap,sizeof(int)*vi->channels);
- memcpy(d->residuesubmap,s->residuesubmap,sizeof(int)*vi->channels);
- memcpy(d->psysubmap,s->psysubmap,sizeof(int)*vi->channels);
+ Why a lookup for each backend in a given mode? Because the
+ blocksize is set by the mode, and low backend lookups may require
+ parameters from other areas of the mode/mapping */
- return(d);
-}
+typedef struct {
+ vorbis_info_mode *mode;
+ vorbis_info_mapping0 *map;
+
+ vorbis_look_time **time_look;
+ vorbis_look_floor **floor_look;
+ vorbis_look_residue **residue_look;
+ vorbis_look_psy *psy_look;
+
+ vorbis_func_time **time_func;
+ vorbis_func_floor **floor_func;
+ vorbis_func_residue **residue_func;
+
+} vorbis_look_mapping0;
-void _vorbis_map0_free(_vi_info_map *i){
+void free_info(vorbis_info_mapping *i){
vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
if(d){
+ if(d->chmuxlist)free(d->chmuxlist);
+ if(d->timesubmap)free(d->timesubmap);
if(d->floorsubmap)free(d->floorsubmap);
if(d->residuesubmap)free(d->residuesubmap);
if(d->psysubmap)free(d->psysubmap);
}
}
-void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb,
- _vi_info_map *source){
+void free_look(vorbis_look_mapping *look){
int i;
- vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)source;
-
- _oggpack_write(opb,d->timesubmap,8);
-
- /* we abbreviate the channel submappings if they all map to the same
- floor/res/psy */
- for(i=1;i<vi->channels;i++)if(d->floorsubmap[i]!=d->floorsubmap[i-1])break;
- if(i==vi->channels){
- _oggpack_write(opb,0,1);
- _oggpack_write(opb,d->floorsubmap[0],8);
- }else{
- _oggpack_write(opb,1,1);
- for(i=0;i<vi->channels;i++)
- _oggpack_write(opb,d->floorsubmap[i],8);
+ vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
+ if(l){
+ for(i=0;i<l->map->submaps;i++){
+ l->time_func[i]->free_look(l->time_look[i]);
+ l->floor_func[i]->free_look(l->floor_look[i]);
+ l->residue_func[i]->free_look(l->residue_look[i]);
+ if(l->psy_look)_vp_psy_clear(l->psy_look+i);
+ }
+ free(l->time_func);
+ free(l->floor_func);
+ free(l->residue_func);
+ free(l->time_look);
+ free(l->floor_look);
+ free(l->residue_look);
+ if(l->psy_look)free(l->psy_look);
+ memset(l,0,sizeof(vorbis_info_mapping0));
+ free(l);
+ }
+}
+
+vorbis_look_mapping *look(vorbis_info *vi,vorbis_info_mode *vm,
+ vorbis_info_mapping *m){
+ int i;
+ vorbis_look_mapping0 *ret=calloc(1,sizeof(vorbis_look_mapping0));
+ vorbis_info_mapping0 *map=ret->map=(vorbis_info_mapping0 *)m;
+ ret->mode=vm;
+
+ ret->time_look=calloc(map->submaps,sizeof(vorbis_look_time *));
+ ret->floor_look=calloc(map->submaps,sizeof(vorbis_look_floor *));
+ ret->residue_look=calloc(map->submaps,sizeof(vorbis_look_residue *));
+ ret->psy_look=calloc(map->submaps,sizeof(vorbis_look_psy));
+
+ ret->time_func=calloc(map->submaps,sizeof(vorbis_func_time *));
+ ret->floor_func=calloc(map->submaps,sizeof(vorbis_func_floor *));
+ ret->residue_func=calloc(map->submaps,sizeof(vorbis_func_residue *));
+
+ for(i=0;i<map->submaps;i++){
+ int timenum=map->timesubmap[i];
+ int floornum=map->floorsubmap[i];
+ int resnum=map->residuesubmap[i];
+
+ ret->time_func[i]=_time_P[vi->time_type[timenum]];
+ ret->time_look[i]=ret->time_func[i]->
+ look(vi,vm,vi->time_param[timenum]);
+ ret->floor_func[i]=_floor_P[vi->floor_type[floornum]];
+ ret->floor_look[i]=ret->floor_func[i]->
+ look(vi,vm,vi->floor_param[floornum]);
+ ret->residue_func[i]=_residue_P[vi->residue_type[resnum]];
+ ret->residue_look[i]=ret->residue_func[i]->
+ look(vi,vm,vi->residue_param[resnum]);
+
+ if(map->psysubmap){
+ int psynum=map->psysubmap[i];
+ _vp_psy_init(ret->psy_look+i,vi->psy_param[psynum],
+ vi->blocksizes[vm->blockflag],vi->rate);
+ }
}
- for(i=1;i<vi->channels;i++)
- if(d->residuesubmap[i]!=d->residuesubmap[i-1])break;
- if(i==vi->channels){
- /* no channel submapping */
- _oggpack_write(opb,0,1);
- _oggpack_write(opb,d->residuesubmap[0],8);
- }else{
- /* channel submapping */
- _oggpack_write(opb,1,1);
+ return(ret);
+}
+
+void pack(vorbis_info *vi,vorbis_info_mapping *vm,oggpack_buffer *opb){
+ int i;
+ vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)vm;
+
+ _oggpack_write(opb,d->submaps,4);
+ /* we don't write the channel submappings if we only have one... */
+ if(d->submaps>1){
for(i=0;i<vi->channels;i++)
- _oggpack_write(opb,d->residuesubmap[i],8);
+ _oggpack_write(opb,d->chmuxlist[i],4);
+ }
+ for(i=0;i<d->submaps;i++){
+ _oggpack_write(opb,d->timesubmap[i],8);
+ _oggpack_write(opb,d->floorsubmap[i],8);
+ _oggpack_write(opb,d->residuesubmap[i],8);
}
}
/* also responsible for range checking */
-extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+vorbis_info_mapping *unpack(vorbis_info *vi,oggpack_buffer *opb){
int i;
vorbis_info_mapping0 *d=calloc(1,sizeof(vorbis_info_mapping0));
memset(d,0,sizeof(vorbis_info_mapping0));
- d->timesubmap=_oggpack_read(opb,8);
- if(d->timesubmap>=vi->times)goto err_out;
+ d->submaps=_oggpack_read(opb,4);
- d->floorsubmap=malloc(sizeof(int)*vi->channels);
- if(_oggpack_read(opb,1)){
- /* channel submap */
- for(i=0;i<vi->channels;i++)
- d->floorsubmap[i]=_oggpack_read(opb,8);
- }else{
- int temp=_oggpack_read(opb,8);
- for(i=0;i<vi->channels;i++)
- d->floorsubmap[i]=temp;
- }
+ d->chmuxlist=calloc(vi->channels,sizeof(int));
+ d->timesubmap=malloc(sizeof(int)*d->submaps);
+ d->floorsubmap=malloc(sizeof(int)*d->submaps);
+ d->residuesubmap=malloc(sizeof(int)*d->submaps);
- d->residuesubmap=malloc(sizeof(int)*vi->channels);
- if(_oggpack_read(opb,1)){
- /* channel submap */
- for(i=0;i<vi->channels;i++)
- d->residuesubmap[i]=_oggpack_read(opb,8);
- }else{
- int temp=_oggpack_read(opb,8);
- for(i=0;i<vi->channels;i++)
- d->residuesubmap[i]=temp;
+ if(d->submaps>1){
+ for(i=0;i<vi->channels;i++){
+ d->chmuxlist[i]=_oggpack_read(opb,4);
+ if(d->chmuxlist[i]>=d->submaps)goto err_out;
+ }
}
-
- 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->residues)
- goto err_out;
+ for(i=0;i<d->submaps;i++){
+ d->timesubmap[i]=_oggpack_read(opb,8);
+ if(d->timesubmap[i]>=vi->times)goto err_out;
+ d->floorsubmap[i]=_oggpack_read(opb,8);
+ if(d->floorsubmap[i]>=vi->floors)goto err_out;
+ d->residuesubmap[i]=_oggpack_read(opb,8);
+ if(d->residuesubmap[i]>=vi->residues)goto err_out;
}
return d;
err_out:
- _vorbis_map0_free(d);
+ free_info(d);
return(NULL);
}
#include "spectrum.h"
/* no time mapping implementation for now */
-int _vorbis_map0_analysis(int mode,vorbis_block *vb){
+int forward(vorbis_block *vb,vorbis_look_mapping *l){
vorbis_dsp_state *vd=vb->vd;
- oggpack_buffer *opb=&vb->opb;
vorbis_info *vi=vd->vi;
- vorbis_info_mapping0 *map=(vorbis_info_mapping0 *)(vi->modelist[mode]);
+ vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+ vorbis_info_mapping0 *map=look->map;
+ vorbis_info_mode *mode=look->mode;
int n=vb->pcmend;
int i,j;
+ double *window=vd->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+
+ double **pcmbundle=alloca(sizeof(double *)*vi->channels);
+ int **auxbundle=alloca(sizeof(int *)*vi->channels);
/* 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];
- }
+ 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 */
/* only MDCT right now.... */
- {
- for(i=0;i<vi->channels;i++){
- double *pcm=vb->pcm[i];
- mdct_forward(vd->transform[vb->W][0],pcm,pcm);
- }
+ for(i=0;i<vi->channels;i++){
+ double *pcm=vb->pcm[i];
+ mdct_forward(vd->transform[vb->W][0],pcm,pcm);
}
{
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);
-
+ int **pcmaux=_vorbis_block_alloc(vb,vi->channels*sizeof(int *));
+
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];
-
+ int submap=map->chmuxlist[i];
+
+ pcmaux[i]=_vorbis_block_alloc(vb,n/2*sizeof(int));
+
/* 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);
+ _vp_mask_floor(look->psy_look+submap,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);
-
- /* perform residue prequantization */
- _vp_quantize(&vd->psy[psysub],pcm,mask,decfloor,pcmaux);
+ look->floor_func[submap]->
+ forward(vb,look->floor_look[submap],floor,decfloor);
+ /* no iterative residue/floor tuning at the moment */
+
+ /* perform residue prequantization. Do it now so we have all
+ the values if we need them */
+ _vp_quantize(look->psy_look+submap,pcm,mask,decfloor,pcmaux[i]);
+
+ }
+
+ /* perform residue encoding with residue mapping; this is
+ multiplexed. All the channels belonging to one submap are
+ encoded (values interleaved), then the next submap, etc */
+
+ for(i=0;i<map->submaps;i++){
+ int ch_in_bundle=0;
+ for(j=0;j<vi->channels;j++){
+ if(map->chmuxlist[j]==i)
+ pcmbundle[ch_in_bundle]=vb->pcm[j];
+ auxbundle[ch_in_bundle++]=pcmaux[j];
+ }
+
+ look->residue_func[i]->forward(vb,look->residue_look[i],pcmbundle,auxbundle,
+ ch_in_bundle);
}
}
- /* 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);
-
-
-
return(0);
}
-int _vorbis_map0_synthesis(int mode,vorbis_block *vb){
-
-
-
- window=vb->vd->window[vb->W][vb->lW][vb->nW];
-
- n=vb->pcmend=vi->blocksize[vb->W];
+int inverse(vorbis_block *vb,vorbis_look_mapping *l){
+ vorbis_dsp_state *vd=vb->vd;
+ vorbis_info *vi=vd->vi;
+ vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+ vorbis_info_mapping0 *map=look->map;
+ vorbis_info_mode *mode=look->mode;
+ int i,j;
+ long n=vb->pcmend=vi->blocksizes[vb->W];
+
+ double *window=vd->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+ double **pcmbundle=alloca(sizeof(double *)*vi->channels);
- /* No envelope encoding yet */
- _oggpack_read(opb,0,1);
+ /* time domain information decode (note that applying the
+ information would have to happen later; we'll probably add a
+ function entry to the harness for that later */
+ /* NOT IMPLEMENTED */
+ /* recover the spectral envelope; store it in the PCM vector for now */
for(i=0;i<vi->channels;i++){
- double *lpc=vb->lpc[i];
- double *lsp=vb->lsp[i];
-
- /* recover the spectral envelope */
- if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
-
- /* recover the spectral residue */
- if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
+ double *pcm=vb->pcm[i];
+ int submap=map->chmuxlist[i];
+ look->floor_func[submap]->inverse(vb,look->floor_look[submap],pcm);
+ }
- /* LSP->LPC */
- vorbis_lsp_to_lpc(lsp,lpc,vl->m);
+ /* recover the residue, apply directly to the spectral envelope */
+ for(i=0;i<map->submaps;i++){
+ int ch_in_bundle=0;
+ for(j=0;j<vi->channels;j++){
+ if(map->chmuxlist[j]==i)
+ pcmbundle[ch_in_bundle++]=vb->pcm[j];
+ }
- /* apply envelope to residue */
-
- vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
-
+ look->residue_func[i]->inverse(vb,look->residue_look[i],pcmbundle,ch_in_bundle);
+ }
- /* MDCT->time */
- mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
-
+ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+ /* only MDCT right now.... */
+ for(i=0;i<vi->channels;i++){
+ double *pcm=vb->pcm[i];
+ mdct_backward(vd->transform[vb->W][0],pcm,pcm);
}
+
+ /* now apply the decoded pre-window time information */
+ /* NOT IMPLEMENTED */
+
+ /* window the data */
+ for(i=0;i<vi->channels;i++){
+ double *pcm=vb->pcm[i];
+ for(j=0;j<n;j++)
+ pcm[j]*=window[j];
+ }
+
+ /* now apply the decoded post-window time information */
+ /* NOT IMPLEMENTED */
+
+ /* all done! */
return(0);
}
********************************************************************
function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.12 2000/01/22 13:28:27 xiphmont Exp $
+ last mod: $Id: psy.c,v 1.13 2000/01/28 09:05:14 xiphmont Exp $
********************************************************************/
}
}
-void _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate){
+void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
long i;
- memset(p,0,sizeof(psy_lookup));
+ memset(p,0,sizeof(vorbis_look_psy));
p->maskthresh=malloc(n*sizeof(double));
p->barknum=malloc(n*sizeof(double));
p->vi=vi;
}
-void _vp_psy_clear(psy_lookup *p){
+void _vp_psy_clear(vorbis_look_psy *p){
if(p){
if(p->maskthresh)free(p->maskthresh);
if(p->barknum)free(p->barknum);
- memset(p,0,sizeof(psy_lookup));
+ memset(p,0,sizeof(vorbis_look_psy));
}
}
/* Masking curve: linear rolloff on a Bark/dB scale, attenuated by
maskthresh */
/* right now, floor==mask */
-void _vp_mask_floor(psy_lookup *p,double *f, double *mask,double *floor){
+void _vp_mask_floor(vorbis_look_psy *p,double *f, double *mask,double *floor){
int n=p->n;
double hroll=p->vi->hrolldB;
double lroll=p->vi->lrolldB;
}
}
-/* for duplicating the info struct */
-
-void *_vi_psy_dup(void *i){
- vorbis_info_psy *source=i;
- if(source){
- vorbis_info_psy *d=malloc(sizeof(vorbis_info_psy));
- memcpy(d,source,sizeof(vorbis_info_psy));
- return(d);
- }else
- return(NULL);
-}
-
-void _vi_psy_free(void *i){
- if(i){
- memset(i,0,sizeof(vorbis_info_psy));
- free(i);
- }
-}
-
********************************************************************
function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.6 2000/01/22 13:28:28 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.7 2000/01/28 09:05:15 xiphmont Exp $
********************************************************************/
double *maskthresh;
double *barknum;
-} psy_lookup;
+} vorbis_look_psy;
-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 _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate);
+extern void _vp_psy_clear(vorbis_look_psy *p);
extern void *_vi_psy_dup(void *source);
extern void _vi_psy_free(void *i);
-extern void _vp_mask_floor(psy_lookup *p,double *pcm,
+extern void _vp_mask_floor(vorbis_look_psy *p,double *pcm,
double *mask,double *floor);
-
+extern void _vp_quantize(vorbis_look_psy *p, double *pcm, double *mask,
+ double *floor,int *aux);
#endif
********************************************************************
function: residue backend 0 implementation
- last mod: $Id: res0.c,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+ last mod: $Id: res0.c,v 1.2 2000/01/28 09:05:16 xiphmont Exp $
********************************************************************/
#include "vorbis/codec.h"
#include "bitwise.h"
#include "registry.h"
-#include "res0.h"
/* unfinished as of 20000118 */
-extern _vi_info_res *_vorbis_res0_dup(_vi_info_res *source){
- vorbis_info_res0 *d=malloc(sizeof(vorbis_info_res0));
- memcpy(d,source,sizeof(vorbis_info_res0));
- d->books=malloc(sizeof(int)*d->stages);
- memcpy(d->books,((vorbis_info_res0 *)source)->books,
- sizeof(int)*d->stages);
- return(d);
-}
-extern void _vorbis_res0_free(_vi_info_res *i){
- vorbis_info_res0 *d=(vorbis_info_res0 *)i;
+void free_info(vorbis_info_residue *i){
+ vorbis_info_residue0 *d=(vorbis_info_residue0 *)i;
if(d){
if(d->books)free(d->books);
- memset(d,0,sizeof(vorbis_info_res0));
+ memset(d,0,sizeof(vorbis_info_residue0));
free(d);
}
}
+void free_look(vorbis_look_residue *i){
+}
+
/* not yet */
-extern void _vorbis_res0_pack(oggpack_buffer *opb, _vi_info_res *vi){
+void pack(vorbis_info_residue *vr,oggpack_buffer *opb){
+}
+
+/* vorbis_info is for range checking */
+vorbis_info_residue *unpack(vorbis_info *vi,oggpack_buffer *opb){
}
-extern _vi_info_res *_vorbis_res0_unpack(vorbis_info *vi,
- oggpack_buffer *opb){
- vorbis_info_res0 d;
- memset(&d,0,sizeof(d));
- return(_vorbis_res0_dup(&d));
+vorbis_look_residue *look (vorbis_info *vi,vorbis_info_mode *vm,
+ vorbis_info_residue *vr){
}
+
+int forward(vorbis_block *vb,vorbis_look_residue *l,double **in,int **aux,int ch){
+}
+int inverse(vorbis_block *vb,vorbis_look_residue *l,double **in,int ch){
+}
+
+vorbis_func_residue residue0_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: spectrum envelope and residue code/decode
- last mod: $Id: spectrum.c,v 1.10 2000/01/05 03:11:03 xiphmont Exp $
-
- ********************************************************************/
-
-#include <stdio.h>
-#include <math.h>
-#include "vorbis/codec.h"
-
-#include "os.h"
-#include "bitwise.h"
-#include "spectrum.h"
-
-/* this code is still seriously abbreviated. I'm filling in pieces as
- we go... --Monty 19991004 */
-
-/* unlike other LPC-based coders, we never apply the filter but only
- inspect the frequency response, thus we don't need to guard against
- instability. However, two coefficients quantising to the same
- value will cause the response to explode. */
-
-int _vs_spectrum_encode(vorbis_block *vb,double amp,double *lsp){
- /* no real coding yet. Just write out full sized words for now
- because people need bitstreams to work with */
-
- int scale=vb->W;
- int m=vb->vd->vi->floororder[scale];
- int n=vb->pcmend*64;
- int last=0;
- double dlast=0.;
- double min=M_PI/n/2.;
-
- int bits=rint(log(n)/log(2));
- int i;
-
-#ifdef TRAIN
- if(amp>0){
- FILE *out;
- if(vb->W)
- out=fopen("lspcoeff-long.vqd","a");
- else
- out=fopen("lspcoeff-short.vqd","a");
-
- for(i=0;i<m;i++)
- fprintf(out,"%lf ",lsp[i]);
- fprintf(out,"\n");
- fclose(out);
-
- if(vb->W)
- out=fopen("lspamp-long.vqd","a");
- else
- out=fopen("lspamp-short.vqd","a");
- fprintf(out,"%lf\n",amp);
- fclose(out);
- }
-#endif
-
- _oggpack_write(&vb->opb,amp*32768,18);
-
- for(i=0;i<m;i++){
- int val=rint(lsp[i]/M_PI*n-last);
- _oggpack_write(&vb->opb,val,bits);
-
- lsp[i]=(last+=val)*M_PI/n;
-
- /* Underpowered but sufficient for now. In the real spec (coming
- soon), a distance of zero can't happen. */
- if(lsp[i]<dlast+min)lsp[i]=dlast+min;
- dlast=lsp[i];
- }
- return(0);
-}
-
-int _vs_spectrum_decode(vorbis_block *vb,double *amp,double *lsp){
- int scale=vb->W;
- int m=vb->vd->vi->floororder[scale];
- int n=vb->pcmend*64;
- int last=0;
- double dlast=0.;
- int bits=rint(log(n)/log(2));
- int i;
- double min=M_PI/n/2.;
-
- *amp=_oggpack_read(&vb->opb,18)/32768.;
-
- for(i=0;i<m;i++){
- int val=_oggpack_read(&vb->opb,bits);
- lsp[i]=(last+=val)*M_PI/n;
-
- /* Underpowered but sufficient */
- if(lsp[i]<dlast+min)lsp[i]=dlast+min;
- dlast=lsp[i];
- }
- return(0);
-}
-
-void _vs_residue_train(vorbis_block *vb,double *data,double *curve,int n){
- int i;
- FILE *out;
- if(vb->W)
- out=fopen("residue-long.vqd","a");
- else
- out=fopen("residue-short.vqd","a");
-
- for(i=0;i<n;i++){
- double val=0;
- if(curve[i]!=0.)val=data[i]/curve[i];
- fprintf(out,"%lf ",val);
- }
- fprintf(out,"\n");
- fclose(out);
-}
-
-void _vs_residue_quantize(double *data,double *curve,
- vorbis_info *vi,int n){
-
- /* The following is temporary, hardwired bullshit */
- int i;
-
- for(i=0;i<n;i++){
- int val=0;
-
- if(curve[i]!=0.)val=rint(data[i]/curve[i]);
- if(val>31)val=31;
- if(val<-31)val=-31;
-
-
- /*if(val==0){
- if(data[i]<0){
- val=-1;
- }else{
- val=1;
- }
- }*/
-
- data[i]=val;
-
- }
-}
-
-int _vs_residue_encode(vorbis_block *vb,double *data){
- /* no real coding yet. Just write out full sized words for now
- because people need bitstreams to work with */
-
- int n=vb->pcmend/2;
- int i;
-
- for(i=0;i<n;i++){
- _oggpack_write(&vb->opb,(int)(data[i]+31),6);
- }
-
- return(0);
-}
-
-int _vs_residue_decode(vorbis_block *vb,double *data){
- /* no real coding yet. Just write out full sized words for now
- because people need bitstreams to work with */
-
- int n=vb->pcmend/2;
- int i;
-
- for(i=0;i<n;i++){
- data[i]=_oggpack_read(&vb->opb,6)-31;
- /*if(data[i]>=0)data[i]+=1;*/
- }
- return(0);
-}
-
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.13 2000/01/10 14:06:31 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.14 2000/01/28 09:05:18 xiphmont Exp $
********************************************************************/
/* uses the local ogg_stream storage in vf; this is important for
non-streaming input sources */
-static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
+static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
+ long *serialno){
ogg_page og;
ogg_packet op;
int i,ret;
/* extract the initial header from the first page and verify that the
Ogg bitstream is in fact Vorbis data */
- vorbis_info_clear(vi);
vorbis_info_init(vi);
+ vorbis_comment_init(vc);
i=0;
while(i<3){
fprintf(stderr,"Corrupt header in logical bitstream.\n");
goto bail_header;
}
- if(vorbis_info_headerin(vi,&op)){
+ if(vorbis_synthesis_headerin(vi,vc,&op)){
fprintf(stderr,"Illegal header in logical bitstream.\n");
goto bail_header;
}
bail_header:
vorbis_info_clear(vi);
+ vorbis_comment_clear(vc);
ogg_stream_clear(&vf->os);
return -1;
}
vorbis_info structs and PCM positions. Only called by the seekable
initialization (local stream storage is hacked slightly; pay
attention to how that's done) */
-static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
+static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
+ vorbis_comment *first_c,
long dataoffset){
ogg_page og;
int i,ret;
vf->serialnos=malloc(vf->links*sizeof(long));
for(i=0;i<vf->links;i++){
- if(first && i==0){
+ if(first_i && first_c && i==0){
/* we already grabbed the initial header earlier. This just
saves the waste of grabbing it again */
- memcpy(vf->vi+i,first,sizeof(vorbis_info));
- memset(first,0,sizeof(vorbis_info));
+ memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
+ memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
vf->dataoffsets[i]=dataoffset;
}else{
/* seek to the location of the initial header */
_seek_helper(vf,vf->offsets[i]);
- if(_fetch_headers(vf,vf->vi+i,NULL)==-1){
- vorbis_info_clear(vf->vi+i);
+ if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL)==-1){
fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
ogg_stream_clear(&vf->os); /* clear local storage. This is not
fprintf(stderr,"Could not find last page of logical "
"bitstream #%d\n\n",i);
vorbis_info_clear(vf->vi+i);
+ vorbis_comment_clear(vf->vc+i);
break;
}
if(ogg_page_frameno(&og)!=-1){
}
static int _open_seekable(OggVorbis_File *vf){
- vorbis_info initial;
+ vorbis_info initial_i;
+ vorbis_comment initial_c;
long serialno,end;
int ret;
long dataoffset;
ogg_page og;
/* is this even vorbis...? */
- memset(&initial,0,sizeof(vorbis_info));
- ret=_fetch_headers(vf,&initial,&serialno);
+ vorbis_info_init(&initial_i);
+ vorbis_comment_init(&initial_c);
+ ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno);
dataoffset=vf->offset;
ogg_stream_clear(&vf->os);
if(ret==-1)return(-1);
}
- _prefetch_all_headers(vf,&initial,dataoffset);
+ _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
ov_raw_seek(vf,0);
return(0);
vf->vi=malloc(sizeof(vorbis_info));
/* Try to fetch the headers, maintaining all the storage */
- if(_fetch_headers(vf,vf->vi,&vf->current_serialno)==-1)return(-1);
+ if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
return 0;
}
/* we're streaming */
/* fetch the three header packets, build the info struct */
- _fetch_headers(vf,vf->vi,&vf->current_serialno);
+ _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
vf->current_link++;
link=0;
}
if(vf->vi && vf->links){
int i;
- for(i=0;i<vf->links;i++)
+ for(i=0;i<vf->links;i++){
vorbis_info_clear(vf->vi+i);
+ vorbis_comment_clear(vf->vc+i);
+ }
free(vf->vi);
}
if(vf->dataoffsets)free(vf->dataoffsets);
}
}
+/* grr, strong typing, grr, no templates/inheritence, grr */
+vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
+ if(vf->seekable){
+ if(link<0)
+ if(vf->decode_ready)
+ return vf->vc+vf->current_link;
+ else
+ return NULL;
+ else
+ if(link>=vf->links)
+ return NULL;
+ else
+ return vf->vc+link;
+ }else{
+ if(vf->decode_ready)
+ return vf->vc;
+ else
+ return NULL;
+ }
+}
+
/* up to this point, everything could more or less hide the multiple
logical bitstream nature of chaining from the toplevel application
if the toplevel application didn't particularly care. However, at
********************************************************************
function: utility functions for loading .vqh and .vqd files
- last mod: $Id: bookutil.c,v 1.6 2000/01/21 13:42:35 xiphmont Exp $
+ last mod: $Id: bookutil.c,v 1.7 2000/01/28 09:05:19 xiphmont Exp $
********************************************************************/
void codebook_unquantize(codebook *b){
long j,k;
- static_codebook *c=b->c;
+ const static_codebook *c=b->c;
double mindel=float24_unpack(c->q_min);
double delta=float24_unpack(c->q_delta);
if(!b->valuelist)b->valuelist=malloc(sizeof(double)*c->entries*c->dim);
int get_vector(codebook *b,FILE *in,int start, int n,double *a){
int i;
- static_codebook *c=b->c;
+ const static_codebook *c=b->c;
while(1){
codebook *codebook_load(char *filename){
codebook *b=calloc(1,sizeof(codebook));
- static_codebook *c=b->c=calloc(1,sizeof(static_codebook));
+ static_codebook *c=(static_codebook *)(b->c=calloc(1,sizeof(static_codebook)));
encode_aux *a=calloc(1,sizeof(encode_aux));
FILE *in=fopen(filename,"r");
char *line;
}
int codebook_entry(codebook *b,double *val){
- static_codebook *c=b->c;
+ const static_codebook *c=b->c;
encode_aux *t=c->encode_tree;
int ptr=0,k;
double *n=alloca(c->dim*sizeof(double));
********************************************************************
function: function calls to collect codebook metrics
- last mod: $Id: metrics.c,v 1.4 2000/01/21 13:42:38 xiphmont Exp $
+ last mod: $Id: metrics.c,v 1.5 2000/01/28 09:05:20 xiphmont Exp $
********************************************************************/
}
if(books){
- static_codebook *b=bs[books-1]->c;
+ const static_codebook *b=bs[books-1]->c;
histogram=calloc(b->entries,sizeof(double));
histogram_distance=calloc(b->entries,sizeof(double));
histogram_errorsq=calloc(b->entries*dim,sizeof(double));
********************************************************************
function: build a VQ codebook and the encoding decision 'tree'
- last mod: $Id: vqsplit.c,v 1.13 2000/01/21 13:42:41 xiphmont Exp $
+ last mod: $Id: vqsplit.c,v 1.14 2000/01/28 09:05:21 xiphmont Exp $
********************************************************************/
long *entryindex=malloc(sizeof(long)*v->entries);
long *pointindex=malloc(sizeof(long)*v->points);
long i,j;
- static_codebook *c=b->c;
+ static_codebook *c=(static_codebook *)b->c;
encode_aux *t;
memset(b,0,sizeof(codebook));