summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2001-05-01 17:08:38 +0000
committerMonty <xiphmont@xiph.org>2001-05-01 17:08:38 +0000
commit960ced80d48ca81fe122ed1c390285df04d4ab64 (patch)
tree5ee55ab05830027dea0f823c8ffe42af83fde382
parent2b1605de070613fa21f435844d9c5ea8a3688f19 (diff)
downloadlibvorbis-git-960ced80d48ca81fe122ed1c390285df04d4ab64.tar.gz
Floor 1 is now functional. Time for full QA.
Monty svn path=/branches/monty-branch-20010404/vorbis/; revision=1437
-rw-r--r--lib/Makefile.am43
-rw-r--r--lib/barkmel.c8
-rw-r--r--lib/floor1.c150
-rw-r--r--lib/info.c589
-rw-r--r--lib/mapping0.c3
-rw-r--r--lib/modes/mode_A.h64
-rw-r--r--lib/vorbisenc.c157
7 files changed, 945 insertions, 69 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 00000000..8751b151
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,43 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = modes books
+
+INCLUDES = -I$(top_srcdir)/include @OGG_CFLAGS@
+
+lib_LTLIBRARIES = libvorbis.la libvorbisfile.la libvorbisenc.la
+
+libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c \
+ lpc.c analysis.c synthesis.c psy.c info.c time0.c \
+ floor1.c floor0.c\
+ res0.c mapping0.c registry.c codebook.c sharedbook.c\
+ lookup.c bitbuffer.c\
+ envelope.h lpc.h lsp.h codebook.h misc.h psy.h\
+ masking.h iir.h os.h mdct.h smallft.h\
+ registry.h scales.h window.h lookup.h lookup_data.h\
+ codec_internal.h backends.h bitbuffer.h
+libvorbis_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@
+
+libvorbisfile_la_SOURCES = vorbisfile.c
+libvorbisfile_la_LDFLAGS = -version-info @VF_LIB_CURRENT@:@VF_LIB_REVISION@:@VF_LIB_AGE@
+
+libvorbisenc_la_SOURCES = vorbisenc.c
+libvorbisenc_la_LDFLAGS = -version-info @VE_LIB_CURRENT@:@VE_LIB_REVISION@:@VE_LIB_AGE@
+
+EXTRA_PROGRAMS = barkmel tone psytune
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+barkmel_SOURCES = barkmel.c
+tone_SOURCES = tone.c
+psytune_SOURCES = psytune.c
+psytune_LDFLAGS = -static
+psytune_LDADD = libvorbis.la
+
+EXTRA_DIST = lookups.pl iir.c
+
+debug:
+ $(MAKE) all CFLAGS="@DEBUG@"
+
+profile:
+ $(MAKE) all CFLAGS="@PROFILE@"
diff --git a/lib/barkmel.c b/lib/barkmel.c
index 1f3ba38c..586dee75 100644
--- a/lib/barkmel.c
+++ b/lib/barkmel.c
@@ -11,7 +11,7 @@
********************************************************************
function: bark scale utility
- last mod: $Id: barkmel.c,v 1.5.4.1 2001/04/29 22:21:04 xiphmont Exp $
+ last mod: $Id: barkmel.c,v 1.5.4.2 2001/05/01 17:08:36 xiphmont Exp $
********************************************************************/
@@ -54,9 +54,9 @@ int main(){
{
float i;
int j;
- for(i=0.,j=0;i<28;i+=.816,j++){
- fprintf(stderr,"(%d) bark=%f %gHz (%d of 1024)\n",
- j,i,fromBARK(i),(int)(fromBARK(i)/22050.*1024.));
+ for(i=0.,j=0;i<28;i+=2.107,j++){
+ fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n",
+ j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.));
}
}
return(0);
diff --git a/lib/floor1.c b/lib/floor1.c
index 84128f80..57870ea6 100644
--- a/lib/floor1.c
+++ b/lib/floor1.c
@@ -11,7 +11,7 @@
********************************************************************
function: floor backend 1 implementation
- last mod: $Id: floor1.c,v 1.1.2.2 2001/04/29 22:21:04 xiphmont Exp $
+ last mod: $Id: floor1.c,v 1.1.2.3 2001/05/01 17:08:36 xiphmont Exp $
********************************************************************/
@@ -121,7 +121,7 @@ static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
- for(k=0;k<info->class_subs[j];k++)
+ for(k=0;k<(1<<info->class_subs[j]);k++)
oggpack_write(opb,info->class_subbook[j][k]+1,8);
}
@@ -140,7 +140,7 @@ static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
codec_setup_info *ci=vi->codec_setup;
- int j,k,count,maxclass=-1,rangebits;
+ int j,k,count=0,maxclass=-1,rangebits;
vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(vorbis_info_floor1));
/* read partitions */
@@ -159,7 +159,7 @@ static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
goto err_out;
- for(k=0;k<info->class_subs[j];k++){
+ for(k=0;k<(1<<info->class_subs[j]);k++){
info->class_subbook[j][k]=oggpack_read(opb,8)-1;
if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
goto err_out;
@@ -278,7 +278,7 @@ static int render_point(int x0,int x1,int y0,int y1,int x){
return(y0+off);
}
-static int FLOOR_todB_LOOKUP[560]={
+static int FLOOR_quantdB_LOOKUP[560]={
1023, 1021, 1019, 1018, 1016, 1014, 1012, 1010,
1008, 1007, 1005, 1003, 1001, 999, 997, 996,
994, 992, 990, 988, 986, 985, 983, 981,
@@ -482,6 +482,22 @@ static int accumulate_fit(float *floor,int x0, int x1,lsfit_acc *a){
return(a->n);
}
+static int add_fit_point(float *floor,int x,lsfit_acc *a){
+ long i;
+
+ int quantized=vorbis_floor1_dBquant(floor+x);
+ if(quantized){
+ a->xa += x;
+ a->ya += quantized;
+ a->x2a += (x*x);
+ a->y2a += quantized*quantized;
+ a->xya += x*quantized;
+ a->n++;
+ return(1);
+ }
+ return(0);
+}
+
/* returns < 0 on too few points to fit, >=0 (meansq error) on success */
static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
long x=0,y=0,x2=0,y2=0,xy=0,n=0,i;
@@ -550,8 +566,8 @@ static int inspect_error(int x0,int x1,int y0,int y1,float *flr,
ady-=abs(base*adx);
if(val){
- if(y-info->maxover>val)return(1);
- if(y+info->maxunder<val)return(1);
+ if(y+info->maxover<val)return(1);
+ if(y-info->maxunder>val)return(1);
mse=(y-val);
mse*=mse;
n++;
@@ -568,8 +584,8 @@ static int inspect_error(int x0,int x1,int y0,int y1,float *flr,
val=vorbis_floor1_dBquant(flr+x);
if(val){
- if(y-info->maxover>val)return(1);
- if(y+info->maxunder<val)return(1);
+ if(y+info->maxover<val)return(1);
+ if(y-info->maxunder>val)return(1);
mse+=((y-val)*(y-val));
n++;
}
@@ -591,6 +607,7 @@ int post_Y(int *A,int *B,int pos){
a dB scale floor, puts out linear */
static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
float *flr){
+ static int seq=0;
long i,j,k,l;
vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
vorbis_info_floor1 *info=look->vi;
@@ -605,8 +622,10 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
int hineighbor[VIF_POSIT+2];
int memo[VIF_POSIT+2];
- static_codebook *sbooks=vb->vd->vi->codec_setup->book_param;
- codebook *books=vb->vd->backend_state->fullbooks;
+ codec_setup_info *ci=vb->vd->vi->codec_setup;
+ static_codebook **sbooks=ci->book_param;
+ codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
+ fullbooks;
memset(fit_flag,0,sizeof(fit_flag));
for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
@@ -618,9 +637,13 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
if(posts==0){
nonzero+=accumulate_fit(flr,0,n,fits);
}else{
- for(i=0;i<posts-1;i++)
+ for(i=0;i<posts-2;i++){
nonzero+=accumulate_fit(flr,look->sorted_index[i],
look->sorted_index[i+1],fits+i);
+ nonzero+=add_fit_point(flr,look->sorted_index[i+1],fits+i);
+ }
+ nonzero+=accumulate_fit(flr,look->sorted_index[i],
+ look->sorted_index[i+1],fits+i);
}
if(nonzero){
@@ -657,6 +680,7 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
/* haven't performed this error search yet */
int lsortpos=look->reverse_index[ln];
int hsortpos=look->reverse_index[hn];
+ memo[ln]=hn;
/* if this is an empty segment, its endpoints don't matter.
Mark as such */
@@ -673,7 +697,6 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
int hx=info->postlist[hn];
int ly=post_Y(fit_valueA,fit_valueB,ln);
int hy=post_Y(fit_valueA,fit_valueB,hn);
- memo[ln]=hn;
if(i<info->searchstart ||
inspect_error(lx,hx,ly,hy,flr,info)){
@@ -685,13 +708,13 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
int lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
int hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
- /* Handle degeneracy */
+ /* Handle degeneracy
if(lmse<0 && hmse<0){
ly0=fit_valueA[ln];
hy1=fit_valueB[hn];
lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
- }
+ }*/
if(lmse<0 && hmse<0) continue;
@@ -734,6 +757,34 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
}
}
}
+
+
+
+ /* generate quantized floor equivalent to what we'd unpack in decode */
+ {
+ int hx;
+ int lx=0;
+ int ly=(post_Y(fit_valueA,fit_valueB,0)+4)>>3;
+
+ for(j=1;j<posts;j++){
+ int current=look->forward_index[j];
+ if(fit_flag[current]){
+ int hy=(post_Y(fit_valueA,fit_valueB,current)+4)>>3;
+ hx=info->postlist[current];
+
+ render_line(lx,hx,ly*2,hy*2,flr);
+
+ lx=hx;
+ ly=hy;
+ }
+ }
+ for(j=hx;j<n;j++)flr[j]=0.f; /* be certain */
+ _analysis_output("infloor",seq,flr,n,0,1);
+
+ }
+
+
+
/* quantize values to multiplier spec */
switch(info->mult){
@@ -763,8 +814,8 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
/* work backward to avoid a copy; unwind the neighbor arrays */
for(i=posts-1;i>1;i--){
int sp=look->reverse_index[i];
- int ln=loneighbor[i];
- int hn=hineighbor[i];
+ int ln=loneighbor[sp];
+ int hn=hineighbor[sp];
int x0=info->postlist[ln];
int x1=info->postlist[hn];
@@ -789,12 +840,12 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
if(val<-headroom)
val=headroom-val-1;
else
- val=1-(val<<1);
+ val=-1-(val<<1);
else
if(val>=headroom)
val= val+headroom;
else
- val>>=1;
+ val<<=1;
fit_valueB[i]=val;
@@ -840,15 +891,15 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
for(k=0;k<csub;k++){
int booknum=info->class_subbook[class][k];
if(booknum<0){
- maxval[k]=0;
+ maxval[k]=1;
}else{
- maxval[k]=sbooks[info->class_subbook[class][k]].entries;
+ maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
}
}
for(k=0;k<cdim;k++){
for(l=0;l<csub;l++){
- val=fit_valueB[j+k];
- if(val<maxval[k]){
+ int val=fit_valueB[j+k];
+ if(val<maxval[l]){
bookas[k]=l;
break;
}
@@ -863,7 +914,7 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
{
FILE *of;
char buffer[80];
- sprintf(buffer,"floor1_class%d.vqd",class);
+ sprintf(buffer,"line%d_class%d.vqd",vb->mode,class);
of=fopen(buffer,"a");
fprintf(of,"%d\n",cval);
fclose(of);
@@ -877,11 +928,12 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
if(book>=0){
vorbis_book_encode(books+book,
fit_valueB[j+k],&vb->opb);
+
#ifdef TRAIN_FLOOR1
{
FILE *of;
char buffer[80];
- sprintf(buffer,"floor1_class%dsub%d.vqd",class,bookas[k]);
+ sprintf(buffer,"line%d_%dsub%d.vqd",vb->mode,class,bookas[k]);
of=fopen(buffer,"a");
fprintf(of,"%d\n",fit_valueB[j+k]);
fclose(of);
@@ -902,29 +954,31 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
int hy=fit_valueA[current]*info->mult;
hx=info->postlist[current];
- render_line(lx,hx,ly,hy,out);
+ render_line(lx,hx,ly,hy,flr);
lx=hx;
ly=hy;
}
- for(j=hx;j<n;j++)out[j]=0.f; /* be certain */
+ for(j=hx;j<n;j++)flr[j]=0.f; /* be certain */
}
}else{
oggpack_write(&vb->opb,0,1);
memset(flr,0,n*sizeof(float));
}
+ seq++;
return(nonzero);
}
-static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
+static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *in,float *out){
+ vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
vorbis_info_floor1 *info=look->vi;
codec_setup_info *ci=vb->vd->vi->codec_setup;
int n=ci->blocksizes[vb->mode]/2;
- int i,j;
- codebook *books=vb->vd->backend_state->fullbooks;
+ int i,j,k;
+ codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
+ fullbooks;
/* unpack wrapped/predicted values from stream */
if(oggpack_read(&vb->opb,1)==1){
@@ -940,32 +994,30 @@ static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
int cdim=info->class_dim[class];
int csubbits=info->class_subs[class];
int csub=1<<csubbits;
- int bookas[8]={0,0,0,0,0,0,0,0};
+ int cval=0;
/* decode the partition's first stage cascade value */
if(csubbits){
- int cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
+ cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
+
if(cval==-1)goto eop;
+ }
- for(k=0;k<cdim;k++){
- int book=info->class_subbook[class][val&(csub-1)];
- cval>>=csubbits;
- if(book>=0){
- if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
- goto eop;
- }else{
- fit_value[j+k]=0;
- }
- }
- }else{
- for(k=0;k<cdim;k++)
+ for(k=0;k<cdim;k++){
+ int book=info->class_subbook[class][cval&(csub-1)];
+ cval>>=csubbits;
+ if(book>=0){
+ if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
+ goto eop;
+ }else{
fit_value[j+k]=0;
- }
+ }
+ }
j+=cdim;
}
/* unwrap positive values and reconsitute via linear interpolation */
- for(i=2;i<posts;i++){
+ for(i=2;i<look->posts;i++){
int predicted=render_point(info->postlist[look->loneighbor[i-2]],
info->postlist[look->hineighbor[i-2]],
fit_value[look->loneighbor[i-2]],
@@ -984,7 +1036,7 @@ static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
}
}else{
if(val&1){
- val= -1 -(val>>1);
+ val= -((val+1)>>1);
}else{
val>>=1;
}
@@ -998,7 +1050,7 @@ static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
int hx;
int lx=0;
int ly=fit_value[0]*info->mult;
- for(j=1;j<posts;j++){
+ for(j=1;j<look->posts;j++){
int current=look->forward_index[j];
int hy=fit_value[current]*info->mult;
hx=info->postlist[current];
diff --git a/lib/info.c b/lib/info.c
new file mode 100644
index 00000000..8c683a1d
--- /dev/null
+++ b/lib/info.c
@@ -0,0 +1,589 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+
+ ********************************************************************
+
+ function: maintain the info structure, info <-> header packets
+ last mod: $Id: info.c,v 1.39.4.1 2001/05/01 17:08:36 xiphmont Exp $
+
+ ********************************************************************/
+
+/* general handling of the header and the vorbis_info structure (and
+ substructures) */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "registry.h"
+#include "window.h"
+#include "psy.h"
+#include "misc.h"
+#include "os.h"
+
+/* helpers */
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+static void _v_writestring(oggpack_buffer *o,char *s){
+ while(*s){
+ oggpack_write(o,*s++,8);
+ }
+}
+
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+ while(bytes--){
+ *buf++=oggpack_read(o,8);
+ }
+}
+
+void vorbis_comment_init(vorbis_comment *vc){
+ memset(vc,0,sizeof(vorbis_comment));
+}
+
+void vorbis_comment_add(vorbis_comment *vc,char *comment){
+ vc->user_comments=_ogg_realloc(vc->user_comments,
+ (vc->comments+2)*sizeof(char *));
+ vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
+ (vc->comments+2)*sizeof(int));
+ vc->user_comments[vc->comments]=strdup(comment);
+ vc->comment_lengths[vc->comments]=strlen(comment);
+ vc->comments++;
+ vc->user_comments[vc->comments]=NULL;
+}
+
+void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){
+ char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
+ strcpy(comment, tag);
+ strcat(comment, "=");
+ strcat(comment, contents);
+ vorbis_comment_add(vc, comment);
+}
+
+/* This is more or less the same as strncasecmp - but that doesn't exist
+ * everywhere, and this is a fairly trivial function, so we include it */
+static int tagcompare(const char *s1, const char *s2, int n){
+ int c=0;
+ while(c < n){
+ if(toupper(s1[c]) != toupper(s2[c]))
+ return !0;
+ c++;
+ }
+ return 0;
+}
+
+char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
+ long i;
+ int found = 0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+ 1);
+
+ strcpy(fulltag, tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
+ if(count == found)
+ /* We return a pointer to the data, not a copy */
+ return vc->user_comments[i] + taglen;
+ else
+ found++;
+ }
+ }
+ return NULL; /* didn't find anything */
+}
+
+int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
+ int i,count=0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+1);
+ strcpy(fulltag,tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen))
+ count++;
+ }
+
+ return count;
+}
+
+void vorbis_comment_clear(vorbis_comment *vc){
+ if(vc){
+ long i;
+ for(i=0;i<vc->comments;i++)
+ if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
+ if(vc->user_comments)_ogg_free(vc->user_comments);
+ if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
+ if(vc->vendor)_ogg_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));
+ vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
+}
+
+void vorbis_info_clear(vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+
+ if(ci){
+
+ for(i=0;i<ci->modes;i++)
+ if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
+
+ for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+ _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
+
+ for(i=0;i<ci->times;i++) /* unpack does the range checking */
+ _time_P[ci->time_type[i]]->free_info(ci->time_param[i]);
+
+ for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+ _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+
+ for(i=0;i<ci->residues;i++) /* unpack does the range checking */
+ _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
+
+ for(i=0;i<ci->books;i++){
+ if(ci->book_param[i]){
+ /* knows if the book was not alloced */
+ vorbis_staticbook_destroy(ci->book_param[i]);
+ }
+ }
+
+ for(i=0;i<ci->psys;i++)
+ _vi_psy_free(ci->psy_param[i]);
+
+ _ogg_free(ci);
+ }
+
+ memset(vi,0,sizeof(vorbis_info));
+}
+
+/* Header packing/unpacking ********************************************/
+
+static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ if(!ci)return(OV_EFAULT);
+
+ vi->version=oggpack_read(opb,32);
+ if(vi->version!=0)return(OV_EVERSION);
+
+ vi->channels=oggpack_read(opb,8);
+ vi->rate=oggpack_read(opb,32);
+
+ vi->bitrate_upper=oggpack_read(opb,32);
+ vi->bitrate_nominal=oggpack_read(opb,32);
+ vi->bitrate_lower=oggpack_read(opb,32);
+
+ ci->blocksizes[0]=1<<oggpack_read(opb,4);
+ ci->blocksizes[1]=1<<oggpack_read(opb,4);
+
+ if(vi->rate<1)goto err_out;
+ if(vi->channels<1)goto err_out;
+ if(ci->blocksizes[0]<8)goto err_out;
+ if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(OV_EBADHEADER);
+}
+
+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;
+ vc->vendor=_ogg_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=_ogg_calloc(vc->comments+1,sizeof(char **));
+ vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(int));
+
+ for(i=0;i<vc->comments;i++){
+ int len=oggpack_read(opb,32);
+ if(len<0)goto err_out;
+ vc->comment_lengths[i]=len;
+ vc->user_comments[i]=_ogg_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_comment_clear(vc);
+ return(OV_EBADHEADER);
+}
+
+/* all of the real encoding details are here. The modes, books,
+ everything */
+static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+ if(!ci)return(OV_EFAULT);
+
+ /* codebooks */
+ ci->books=oggpack_read(opb,8)+1;
+ /*ci->book_param=_ogg_calloc(ci->books,sizeof(static_codebook *));*/
+ for(i=0;i<ci->books;i++){
+ ci->book_param[i]=_ogg_calloc(1,sizeof(static_codebook));
+ if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
+ }
+
+ /* time backend settings */
+ ci->times=oggpack_read(opb,6)+1;
+ /*ci->time_type=_ogg_malloc(ci->times*sizeof(int));*/
+ /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/
+ for(i=0;i<ci->times;i++){
+ ci->time_type[i]=oggpack_read(opb,16);
+ if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out;
+ ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb);
+ if(!ci->time_param[i])goto err_out;
+ }
+
+ /* floor backend settings */
+ ci->floors=oggpack_read(opb,6)+1;
+ /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(int));*/
+ /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
+ for(i=0;i<ci->floors;i++){
+ ci->floor_type[i]=oggpack_read(opb,16);
+ if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
+ ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+ if(!ci->floor_param[i])goto err_out;
+ }
+
+ /* residue backend settings */
+ ci->residues=oggpack_read(opb,6)+1;
+ /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(int));*/
+ /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
+ for(i=0;i<ci->residues;i++){
+ ci->residue_type[i]=oggpack_read(opb,16);
+ if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
+ ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
+ if(!ci->residue_param[i])goto err_out;
+ }
+
+ /* map backend settings */
+ ci->maps=oggpack_read(opb,6)+1;
+ /*ci->map_type=_ogg_malloc(ci->maps*sizeof(int));*/
+ /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
+ for(i=0;i<ci->maps;i++){
+ ci->map_type[i]=oggpack_read(opb,16);
+ if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
+ ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
+ if(!ci->map_param[i])goto err_out;
+ }
+
+ /* mode settings */
+ ci->modes=oggpack_read(opb,6)+1;
+ /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
+ for(i=0;i<ci->modes;i++){
+ ci->mode_param[i]=_ogg_calloc(1,sizeof(vorbis_info_mode));
+ ci->mode_param[i]->blockflag=oggpack_read(opb,1);
+ ci->mode_param[i]->windowtype=oggpack_read(opb,16);
+ ci->mode_param[i]->transformtype=oggpack_read(opb,16);
+ ci->mode_param[i]->mapping=oggpack_read(opb,8);
+
+ if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+ if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+ if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
+ }
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(OV_EBADHEADER);
+}
+
+/* The Vorbis header is in three packets; the initial small packet in
+ the first page that identifies basic parameters, a second packet
+ with bitstream comments and a third packet that holds the
+ codebook. */
+
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
+ oggpack_buffer opb;
+
+ if(op){
+ oggpack_readinit(&opb,op->packet,op->bytes);
+
+ /* Which of the three types of header is this? */
+ /* Also verify header-ness, vorbis */
+ {
+ char buffer[6];
+ int packtype=oggpack_read(&opb,8);
+ memset(buffer,0,6);
+ _v_readstring(&opb,buffer,6);
+ if(memcmp(buffer,"vorbis",6)){
+ /* not a vorbis header */
+ return(OV_ENOTVORBIS);
+ }
+ switch(packtype){
+ case 0x01: /* least significant *bit* is read first */
+ if(!op->b_o_s){
+ /* Not the initial packet */
+ return(OV_EBADHEADER);
+ }
+ if(vi->rate!=0){
+ /* previously initialized info header */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_info(vi,&opb));
+
+ case 0x03: /* least significant *bit* is read first */
+ if(vi->rate==0){
+ /* um... we didn't get the initial header */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_comment(vc,&opb));
+
+ case 0x05: /* least significant *bit* is read first */
+ if(vi->rate==0 || vc->vendor==NULL){
+ /* um... we didn;t get the initial header or comments yet */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_books(vi,&opb));
+
+ default:
+ /* Not a valid vorbis header type */
+ return(OV_EBADHEADER);
+ break;
+ }
+ }
+ }
+ return(OV_EBADHEADER);
+}
+
+/* pack side **********************************************************/
+
+static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ if(!ci)return(OV_EFAULT);
+
+ /* preamble */
+ oggpack_write(opb,0x01,8);
+ _v_writestring(opb,"vorbis");
+
+ /* basic information about the stream */
+ oggpack_write(opb,0x00,32);
+ oggpack_write(opb,vi->channels,8);
+ oggpack_write(opb,vi->rate,32);
+
+ oggpack_write(opb,vi->bitrate_upper,32);
+ oggpack_write(opb,vi->bitrate_nominal,32);
+ oggpack_write(opb,vi->bitrate_lower,32);
+
+ oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
+ oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+ char temp[]="Xiphophorus libVorbis I 20010501";
+
+ /* preamble */
+ oggpack_write(opb,0x03,8);
+ _v_writestring(opb,"vorbis");
+
+ /* vendor */
+ oggpack_write(opb,strlen(temp),32);
+ _v_writestring(opb,temp);
+
+ /* comments */
+
+ oggpack_write(opb,vc->comments,32);
+ if(vc->comments){
+ int i;
+ for(i=0;i<vc->comments;i++){
+ if(vc->user_comments[i]){
+ oggpack_write(opb,vc->comment_lengths[i],32);
+ _v_writestring(opb,vc->user_comments[i]);
+ }else{
+ oggpack_write(opb,0,32);
+ }
+ }
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+ if(!ci)return(OV_EFAULT);
+
+ oggpack_write(opb,0x05,8);
+ _v_writestring(opb,"vorbis");
+
+ /* books */
+ oggpack_write(opb,ci->books-1,8);
+ for(i=0;i<ci->books;i++)
+ if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
+
+ /* times */
+ oggpack_write(opb,ci->times-1,6);
+ for(i=0;i<ci->times;i++){
+ oggpack_write(opb,ci->time_type[i],16);
+ _time_P[ci->time_type[i]]->pack(ci->time_param[i],opb);
+ }
+
+ /* floors */
+ oggpack_write(opb,ci->floors-1,6);
+ for(i=0;i<ci->floors;i++){
+ oggpack_write(opb,ci->floor_type[i],16);
+ _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
+ }
+
+ /* residues */
+ oggpack_write(opb,ci->residues-1,6);
+ for(i=0;i<ci->residues;i++){
+ oggpack_write(opb,ci->residue_type[i],16);
+ _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
+ }
+
+ /* maps */
+ oggpack_write(opb,ci->maps-1,6);
+ for(i=0;i<ci->maps;i++){
+ oggpack_write(opb,ci->map_type[i],16);
+ _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
+ }
+
+ /* modes */
+ oggpack_write(opb,ci->modes-1,6);
+ for(i=0;i<ci->modes;i++){
+ oggpack_write(opb,ci->mode_param[i]->blockflag,1);
+ oggpack_write(opb,ci->mode_param[i]->windowtype,16);
+ oggpack_write(opb,ci->mode_param[i]->transformtype,16);
+ oggpack_write(opb,ci->mode_param[i]->mapping,8);
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+err_out:
+ return(-1);
+}
+
+int vorbis_commentheader_out(vorbis_comment *vc,
+ ogg_packet *op){
+
+ oggpack_buffer opb;
+
+ oggpack_writeinit(&opb);
+ if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL;
+
+ op->packet = _ogg_malloc(oggpack_bytes(&opb));
+ memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
+
+ op->bytes=oggpack_bytes(&opb);
+ op->b_o_s=0;
+ op->e_o_s=0;
+ op->granulepos=0;
+
+ return 0;
+}
+
+int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code){
+ int ret=OV_EIMPL;
+ vorbis_info *vi=v->vi;
+ oggpack_buffer opb;
+ backend_lookup_state *b=v->backend_state;
+
+ if(!b){
+ ret=OV_EFAULT;
+ goto err_out;
+ }
+
+ /* first header packet **********************************************/
+
+ oggpack_writeinit(&opb);
+ if(_vorbis_pack_info(&opb,vi))goto err_out;
+
+ /* build the packet */
+ if(b->header)_ogg_free(b->header);
+ b->header=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
+ op->packet=b->header;
+ op->bytes=oggpack_bytes(&opb);
+ op->b_o_s=1;
+ op->e_o_s=0;
+ op->granulepos=0;
+
+ /* second header packet (comments) **********************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_comment(&opb,vc))goto err_out;
+
+ if(b->header1)_ogg_free(b->header1);
+ b->header1=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
+ op_comm->packet=b->header1;
+ op_comm->bytes=oggpack_bytes(&opb);
+ op_comm->b_o_s=0;
+ op_comm->e_o_s=0;
+ op_comm->granulepos=0;
+
+ /* third header packet (modes/codebooks) ****************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_books(&opb,vi))goto err_out;
+
+ if(b->header2)_ogg_free(b->header2);
+ b->header2=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
+ op_code->packet=b->header2;
+ op_code->bytes=oggpack_bytes(&opb);
+ op_code->b_o_s=0;
+ op_code->e_o_s=0;
+ op_code->granulepos=0;
+
+ oggpack_writeclear(&opb);
+ return(0);
+ err_out:
+ oggpack_writeclear(&opb);
+ memset(op,0,sizeof(ogg_packet));
+ memset(op_comm,0,sizeof(ogg_packet));
+ memset(op_code,0,sizeof(ogg_packet));
+
+ if(b->header)_ogg_free(b->header);
+ if(b->header1)_ogg_free(b->header1);
+ if(b->header2)_ogg_free(b->header2);
+ b->header=NULL;
+ b->header1=NULL;
+ b->header2=NULL;
+ return(ret);
+}
+
diff --git a/lib/mapping0.c b/lib/mapping0.c
index 0e02d9f1..00ef2598 100644
--- a/lib/mapping0.c
+++ b/lib/mapping0.c
@@ -11,7 +11,7 @@
********************************************************************
function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.27.4.1 2001/04/29 22:21:04 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.27.4.2 2001/05/01 17:08:36 xiphmont Exp $
********************************************************************/
@@ -297,7 +297,6 @@ static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){
#endif
}
- seq++;
vbi->ampmax=newmax;
/* perform residue encoding with residue mapping; this is
diff --git a/lib/modes/mode_A.h b/lib/modes/mode_A.h
index 09694c04..6b493eed 100644
--- a/lib/modes/mode_A.h
+++ b/lib/modes/mode_A.h
@@ -11,7 +11,7 @@
********************************************************************
function: predefined encoding modes
- last mod: $Id: mode_A.h,v 1.14.4.1 2001/04/29 22:21:06 xiphmont Exp $
+ last mod: $Id: mode_A.h,v 1.14.4.2 2001/05/01 17:08:38 xiphmont Exp $
********************************************************************/
@@ -22,10 +22,8 @@
#include "vorbis/codec.h"
#include "backends.h"
-#include "books/lsp12_0.vqh"
-#include "books/lsp30_0.vqh"
-#include "books/lsp12_1.vqh"
-#include "books/lsp30_1.vqh"
+#include "books/line0.vqh"
+#include "books/line1.vqh"
#include "books/res0_128_128aux.vqh"
#include "books/res0_128_1024aux.vqh"
@@ -228,10 +226,48 @@ static vorbis_info_psy _psy_set_A={
/* with GNUisms, this could be short and readable. Oh well */
static vorbis_info_time0 _time_set0A={0};
-static vorbis_info_floor0 _floor_set0A={12, 44100, 64, 10,130, 2, {0,1},
- 0.199f, .285f};
-static vorbis_info_floor0 _floor_set1A={30, 44100, 256, 12,150, 2, {2,3},
- .082f, .126f};
+/*static vorbis_info_floor0 _floor_set0A={12, 44100, 64, 10,130, 2, {0,1},
+ 0.199f, .285f};*/
+/*static vorbis_info_floor0 _floor_set1A={30, 44100, 256, 12,150, 2, {2,3},
+ .082f, .126f};*/
+
+static vorbis_info_floor1 _floor_set0A={4,
+ {0,1,2,2},
+
+ {2,3,3},
+ {1,1,1},
+ {0,0,0},
+ {{-1,1},{-1,1},{-1,1}},
+
+ 2,
+ {0,128,
+ 5,21,
+
+ 2,1,3,
+ 11,7,15,
+ 45,30,73},
+
+ 40,8,200,4};
+
+static vorbis_info_floor1 _floor_set1A={10,
+ {0,1,2,2,2,2,3,3,3,3},
+
+ {3,4,3,3},
+ {1,1,1,1},
+ {2,2,2,2},
+ {{-1,3},{-1,3},{-1,3},{-1,3}},
+
+ 2,
+ {0,1024,
+ 88,31,243,
+ 14,54,143,460,
+
+ 6,3,10, 22,18,26, 41,36,47,
+ 69,61,78, 112,99,126, 185,162,211,
+ 329,282,387, 672,553,825},
+
+ 40,8,200,9};
+
static vorbis_info_residue0 _residue_set0A={0,96,16,6,4,
{0,1,1,1,1,1},
{6,7,8,9,10},
@@ -271,14 +307,14 @@ codec_setup_info info_A={
/* times */
{0,0},{&_time_set0A},
/* floors */
- {0,0},{&_floor_set0A,&_floor_set1A},
+ {1,1},{&_floor_set0A,&_floor_set1A},
/* residue */
{0,0},{&_residue_set0A,&_residue_set1A},
/* books */
- {&_vq_book_lsp12_0, /* 0 */
- &_vq_book_lsp12_1, /* 1 */
- &_vq_book_lsp30_0, /* 2 */
- &_vq_book_lsp30_1, /* 3 */
+ {&_huff_book_line0,
+ &_huff_book_line1,
+ &_huff_book_line0,
+ &_huff_book_line1,
&_huff_book_res0_128_128aux,
&_huff_book_res0_128_1024aux,
diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c
new file mode 100644
index 00000000..91f1f72e
--- /dev/null
+++ b/lib/vorbisenc.c
@@ -0,0 +1,157 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+
+ ********************************************************************
+
+ function: simple programmatic interface for encoder mode setup
+ last mod: $Id: vorbisenc.c,v 1.6.4.1 2001/05/01 17:08:36 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "vorbis/codec.h"
+#include "vorbis/vorbisenc.h"
+
+#include "codec_internal.h"
+#include "registry.h"
+#include "modes/modes.h"
+
+#include "os.h"
+#include "misc.h"
+
+
+/* deepcopy all but the codebooks; in this usage, they're static
+ (don't copy as they could be big) */
+static void codec_setup_partialcopy(codec_setup_info *ci,
+ codec_setup_info *cs){
+ int i;
+
+ memcpy(ci,cs,sizeof(codec_setup_info)); /* to get the flat numbers */
+
+ /* codebooks */
+ for(i=0;i<ci->books;i++){
+ ci->book_param[i]=cs->book_param[i];
+ }
+
+ /* time backend settings */
+ for(i=0;i<ci->times;i++){
+ ci->time_param[i]=_time_P[ci->time_type[i]]->
+ copy_info(cs->time_param[i]);
+ }
+
+ /* floor backend settings */
+ for(i=0;i<ci->floors;i++){
+ ci->floor_param[i]=_floor_P[ci->floor_type[i]]->
+ copy_info(cs->floor_param[i]);
+ }
+
+ /* residue backend settings */
+ for(i=0;i<ci->residues;i++){
+ ci->residue_param[i]=_residue_P[ci->residue_type[i]]->
+ copy_info(cs->residue_param[i]);
+ }
+
+ /* map backend settings */
+ for(i=0;i<ci->maps;i++){
+ ci->map_param[i]=_mapping_P[ci->map_type[i]]->
+ copy_info(cs->map_param[i]);
+ }
+
+ /* mode settings */
+ for(i=0;i<ci->modes;i++){
+ ci->mode_param[i]=_ogg_calloc(1,sizeof(vorbis_info_mode));
+ ci->mode_param[i]->blockflag=cs->mode_param[i]->blockflag;
+ ci->mode_param[i]->windowtype=cs->mode_param[i]->windowtype;
+ ci->mode_param[i]->transformtype=cs->mode_param[i]->transformtype;
+ ci->mode_param[i]->mapping=cs->mode_param[i]->mapping;
+ }
+
+ /* psy settings */
+ for(i=0;i<ci->psys;i++){
+ ci->psy_param[i]=_vi_psy_copy(cs->psy_param[i]);
+ }
+
+}
+
+/* right now, this just encapsultes the old modes behind the interface
+ we'll be using from here on out. After beta 3, the new bitrate
+ tracking/modding/tuning engine will lurk inside */
+/* encoders will need to use vorbis_info_init beforehand and call
+ vorbis_info clear when all done */
+
+int vorbis_encode_init(vorbis_info *vi,
+ long channels,
+ long rate,
+
+ long max_bitrate,
+ long nominal_bitrate,
+ long min_bitrate){
+
+ long bpch;
+ int i,j;
+ codec_setup_info *ci=vi->codec_setup;
+ codec_setup_info *mode=NULL;
+ if(!ci)return(OV_EFAULT);
+
+ vi->version=0;
+ vi->channels=channels;
+ vi->rate=rate;
+
+ vi->bitrate_upper=max_bitrate;
+ vi->bitrate_nominal=nominal_bitrate;
+ vi->bitrate_lower=min_bitrate;
+ vi->bitrate_window=2;
+
+ /* copy a mode into our allocated storage */
+ bpch=nominal_bitrate/channels;
+ if(bpch<60000){
+ /* mode A */
+ mode=&info_AA;
+ }else if(bpch<75000){
+ /* mode A */
+ mode=&info_A;
+ }else if(bpch<90000){
+ /* mode B */
+ mode=&info_B;
+ }else if(bpch<110000){
+ /* mode C */
+ mode=&info_C;
+ }else if(bpch<160000){
+ /* mode D */
+ mode=&info_D;
+ }else{
+ /* mode E */
+ mode=&info_E;
+ }
+
+ /* now we have to deepcopy */
+ codec_setup_partialcopy(ci,mode);
+
+ /* adjust for sample rate */
+ for(i=0;i<ci->floors;i++)
+ if(ci->floor_type[i]==0)
+ ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate;
+
+ /* adjust for channels; all our mappings use submap zero now */
+ /* yeah, OK, _ogg_calloc did this for us. But it's a reminder/placeholder */
+ for(i=0;i<ci->maps;i++)
+ for(j=0;j<channels;j++)
+ ((vorbis_info_mapping0 *)ci->map_param[i])->chmuxlist[j]=0;
+
+ return(0);
+}
+
+int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
+ return(OV_EIMPL);
+}
+