/********** Decode setup ************/
ogg_sync_init(&oy); /* Now we can read pages */
-
+
while(1){ /* we repeat if the bitstream is chained */
int eos=0;
int i;
buffer=ogg_sync_buffer(&oy,4096);
bytes=fread(buffer,1,4096,stdin);
ogg_sync_wrote(&oy,bytes);
-
+
/* Get the first page. */
if(ogg_sync_pageout(&oy,&og)!=1){
/* have we simply run out of data? If so, we're done. */
if(bytes<4096)break;
-
+
/* error case. Must not be Vorbis data */
fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
exit(1);
}
-
+
/* Get the serial number and set up the rest of decode. */
/* serialno first; use it to set up a logical stream */
ogg_stream_init(&os,ogg_page_serialno(&og));
-
+
/* extract the initial header from the first page and verify that the
Ogg bitstream is in fact Vorbis data */
-
+
/* I handle the initial header first instead of just having the code
read all three Vorbis headers at once because reading the initial
header is an easy way to identify a Vorbis bitstream and it's
useful to see that functionality seperated out. */
-
+
vorbis_info_init(&vi);
vorbis_comment_init(&vc);
- if(ogg_stream_pagein(&os,&og)<0){
+ if(ogg_stream_pagein(&os,&og)<0){
/* error; stream version mismatch perhaps */
fprintf(stderr,"Error reading first page of Ogg bitstream data.\n");
exit(1);
}
-
- if(ogg_stream_packetout(&os,&op)!=1){
+
+ if(ogg_stream_packetout(&os,&op)!=1){
/* no page? must not be vorbis */
fprintf(stderr,"Error reading initial header packet.\n");
exit(1);
}
-
- if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){
+
+ if(vorbis_synthesis_headerin(&vi,&vc,&op)<0){
/* error case; not a vorbis header */
fprintf(stderr,"This Ogg bitstream does not contain Vorbis "
"audio data.\n");
exit(1);
}
-
+
/* At this point, we're sure we're Vorbis. We've set up the logical
(Ogg) bitstream decoder. Get the comment and codebook headers and
set up the Vorbis decoder */
-
+
/* The next two packets in order are the comment and codebook headers.
They're likely large and may span multiple pages. Thus we read
and submit data until we get our two packets, watching that no
pages are missing. If a page is missing, error out; losing a
header page is the only place where missing data is fatal. */
-
+
i=0;
while(i<2){
while(i<2){
}
ogg_sync_wrote(&oy,bytes);
}
-
+
/* Throw the comments plus a few lines about the bitstream we're
decoding */
{
fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi.channels,vi.rate);
fprintf(stderr,"Encoded by: %s\n\n",vc.vendor);
}
-
+
convsize=4096/vi.channels;
/* OK, got and parsed all three headers. Initialize the Vorbis
proceed in parallel. We could init
multiple vorbis_block structures
for vd here */
-
+
/* The rest is just a straight decode loop until end of stream */
while(!eos){
while(!eos){
this point */
while(1){
result=ogg_stream_packetout(&os,&op);
-
+
if(result==0)break; /* need more data */
if(result<0){ /* missing or corrupt data at this page position */
/* no reason to complain; already complained above */
/* we have a packet. Decode it */
float **pcm;
int samples;
-
+
if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
vorbis_synthesis_blockin(&vd,&vb);
- /*
-
+ /*
+
**pcm is a multichannel float vector. In stereo, for
example, pcm[0] is left, and pcm[1] is right. samples is
the size of each channel. Convert the float values
(-1.<=range<=1.) to whatever PCM format and write it out */
-
+
while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){
int j;
int clipflag=0;
int bout=(samples<convsize?samples:convsize);
-
+
/* convert floats to 16 bit signed ints (host order) and
interleave */
for(i=0;i<vi.channels;i++){
ptr+=vi.channels;
}
}
-
+
if(clipflag)
fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence));
-
-
+
+
fwrite(convbuffer,2*vi.channels,bout,stdout);
-
+
vorbis_synthesis_read(&vd,bout); /* tell libvorbis how
many samples we
actually consumed */
- }
+ }
}
}
if(ogg_page_eos(&og))eos=1;
if(bytes==0)eos=1;
}
}
-
+
/* ogg_page and ogg_packet structs always point to storage in
libvorbis. They're never freed or manipulated directly */
-
+
vorbis_block_clear(&vb);
vorbis_dsp_clear(&vd);
}else{
/* clean up this logical bitstream; before exit we see if we're
followed by another [chained] */
-
+
ogg_stream_clear(&os);
vorbis_comment_clear(&vc);
vorbis_info_clear(&vi); /* must be called last */
/* OK, clean up the framer */
ogg_sync_clear(&oy);
-
+
fprintf(stderr,"Done.\n");
return(0);
}
{
fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
timelength);
-
+
for(i=0;i<1000;i++){
double val=(double)rand()/RAND_MAX*timelength;
fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
{
fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
timelength);
-
+
for(i=0;i<1000;i++){
double val=(double)rand()/RAND_MAX*timelength;
fprintf(stderr,"\r\t%d [time position %f]... ",i,val);
}
}
-
+
fprintf(stderr,"\r \nOK.\n\n");
int current_section;
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
- /* Beware the evil ifdef. We avoid these where we can, but this one we
+ /* Beware the evil ifdef. We avoid these where we can, but this one we
cannot. Don't add any more, you'll probably go to hell if you do. */
_setmode( _fileno( stdin ), _O_BINARY );
_setmode( _fileno( stdout ), _O_BINARY );
(long)ov_pcm_total(&vf,-1));
fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor);
}
-
+
while(!eof){
long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,¤t_section);
if (ret == 0) {
/* cleanup */
ov_clear(&vf);
-
+
fprintf(stderr,"Done.\n");
return(0);
}
static vorbis_info_psy_global _psy_set0G={
0, /* decaydBpms */
8, /* lines per eighth octave */
-
+
/* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
- -6.f,
-
+ -6.f,
+
0,
0.,
static vorbis_info_psy _psy_set0={
ATH_Bark_dB_lineaggressive,
-
+
-100.f,
-140.f,
6.f, /* floor master att */
.900f, 0.f, /*11500*/
.900f, 1.f, /*16000*/
},
-
+
95.f, /* even decade + 5 is important; saves an rint() later in a
tight loop) */
-44.,
static vorbis_info_floor1 _floor_set0={1,
{0},
-
+
{32},
{0},
{0},
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,
+
+ 6,3,10, 22,18,26, 41,36,47,
+ 69,61,78, 112,99,126, 185,162,211,
329,282,387, 672,553,825
},
-
+
60,30,400,
20,8,1,18.,
20,600,
static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}};
-static codec_setup_info codec_setup0={ {0,0},
- 1,1,1,1,1,0,1,
+static codec_setup_info codec_setup0={ {0,0},
+ 1,1,1,1,1,0,1,
{NULL},
{0},{&mapping_info},
{0},{NULL},
{NULL},
{&_psy_set0},
&_psy_set0G};
-
+
static int noisy=0;
void analysis(char *base,int i,float *v,int n,int bark,int dB){
if(noisy){
fprintf(of,"%g ",toBARK(22050.f*j/n));
else
fprintf(of,"%g ",(float)j);
-
+
if(dB){
fprintf(of,"%g\n",todB(v+j));
}else{
framesize=atoi(argv[0]);
argv++;
}
-
+
vi.channels=2;
vi.codec_setup=&codec_setup0;
/* we cheat on the WAV header; we just bypass 44 bytes and never
verify that it matches 16bit/stereo/44.1kHz. */
-
+
fread(buffer,1,44,stdin);
fwrite(buffer,1,44,stdout);
memset(buffer,0,framesize*2);
fprintf(stderr,"Processing for frame size %d...\n",framesize);
while(!eos){
- long bytes=fread(buffer2,1,framesize*2,stdin);
+ long bytes=fread(buffer2,1,framesize*2,stdin);
if(bytes<framesize*2)
memset(buffer2+bytes,0,framesize*2-bytes);
-
+
if(bytes!=0){
int nonzero[2];
pcm[1][i]=((buffer[i*4+3]<<8)|
(0x00ff&(int)buffer[i*4+2]))/32768.f;
}
-
+
{
float secs=framesize/44100.;
-
+
ampmax+=secs*ampmax_att_per_sec;
if(ampmax<-9999)ampmax=-9999;
}
float *logmdct=mdct+framesize/2;
analysis("pre",frameno+i,pcm[i],framesize,0,0);
-
+
/* fft and mdct transforms */
for(j=0;j<framesize;j++)
fft[j]=pcm[i][j]*=window[j];
-
+
drft_forward(&f_look,fft);
local_ampmax[i]=-9999.f;
if(temp>local_ampmax[i])local_ampmax[i]=temp;
}
if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i];
-
+
mdct_forward(&m_look,pcm[i],mdct);
for(j=0;j<framesize/2;j++)
logmdct[j]=todB(mdct+j);
logmdct,
mask,
logmax,
-
+
flr[i]);
}
for(j=0;j<framesize/2;j++)
if(fabs(pcm[i][j])>1500)
fprintf(stderr,"%ld ",frameno+i);
-
+
analysis("res",frameno+i,pcm[i],framesize/2,1,0);
analysis("codedflr",frameno+i,flr[i],framesize/2,1,1);
}
&vi,
pcm,
nonzero);
-
+
for(i=0;i<2;i++)
analysis("quant",frameno+i,pcm[i],framesize/2,1,0);
&mapping_info,
pcm,
nonzero);
-
+
for(i=0;i<2;i++)
analysis("coupled",frameno+i,pcm[i],framesize/2,1,0);
for(i=mapping_info.coupling_steps-1;i>=0;i--){
float *pcmM=pcm[mapping_info.coupling_mag[i]];
float *pcmA=pcm[mapping_info.coupling_ang[i]];
-
+
for(j=0;j<framesize/2;j++){
float mag=pcmM[j];
float ang=pcmA[j];
-
+
if(mag>0)
if(ang>0){
pcmM[j]=mag;
}
}
}
-
+
for(i=0;i<2;i++)
analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0);
}
-
+
/* write data. Use the part of buffer we're about to shift out */
for(i=0;i<2;i++){
char *ptr=buffer+i*2;
ptr+=4;
}
}
-
+
fprintf(stderr,"*");
fwrite(buffer,1,framesize*2,stdout);
memmove(buffer,buffer2,framesize*2);
if(!ci->mode_param[mode]){
return(OV_EBADPACKET);
}
-
+
vb->W=ci->mode_param[mode]->blockflag;
if(vb->W){
vb->lW=oggpack_read(opb,1);
int i,j;
double *f;
double *amp;
-
+
if(argc<2)usage();
f=alloca(sizeof(*f)*(argc-1));
i=0;
while(argv[i+1]){
char *pos=strchr(argv[i+1],',');
-
+
f[i]=atof(argv[i+1]);
if(pos)
amp[i]=atof(pos+1)*32767.f;
while(!gotline){
if(sofar+1>=lbufsize){
- if(!lbufsize){
+ if(!lbufsize){
lbufsize=1024;
linebuffer=_ogg_malloc(lbufsize);
}else{
}
}
}
-
+
if(linebuffer[0]=='#'){
sofar=0;
}else{
for(i=1;i<c->dim;i++)
if(get_line_value(in,a+i))
break;
-
+
if(i==c->dim){
float temp=a[c->dim-1];
for(i=0;i<c->dim;i++)a[i]-=sequence_base;
fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
exit(1);
}
-
+
switch(c->maptype){
case 0:
quant_to_read=0;
quant_to_read=c->entries*c->dim;
break;
}
-
+
/* load the quantized entries */
find_seek_to(in,"static const long _vq_quantlist_");
reset_next_value();
fprintf(stderr,"out of data while reading codebook %s\n",filename);
exit(1);
}
-
+
/* load the lengthlist */
find_seek_to(in,"_lengthlist");
reset_next_value();
/* got it all */
fclose(in);
-
+
vorbis_book_init_encode(b,c);
b->valuelist=_book_unquantize(c,c->entries,NULL);
for(i=vals;i>1;i--){
int first=-1,second=-1;
long least=-1;
-
+
spinnit("building... ",i);
-
+
/* find the two nodes to join */
for(j=0;j<vals;j++)
if(least==-1 || hist[j]<=least){
fprintf(stderr,"huffman fault; no free branch\n");
exit(1);
}
-
+
/* join them */
least=hist[first]+hist[second];
for(j=0;j<vals;j++)
fprintf(stderr,"\rEliminating %d unused entries; %d entries remain\n",
vals-upper,upper);
}
-
+
build_tree_from_lengths(upper,newhist,lengthlist);
-
+
upper=0;
for(i=0;i<vals;i++)
if(hist[i]>0)
fprintf(out,"};\n\n");
/* tie it all together */
-
+
fprintf(out,"static const static_codebook %s = {\n",name);
-
+
fprintf(out,"\t%ld, %ld,\n",c->dim,c->entries);
fprintf(out,"\t(char *)_vq_lengthlist_%s,\n",name);
fprintf(out,"\t%d, %ld, %ld, %d, %d,\n",
if(c->lengthlist[j]){
int indexdiv=1;
printf("%4d: ",j);
- for(k=0;k<b->dim;k++){
+ for(k=0;k<b->dim;k++){
int index= (j/indexdiv)%bins;
printf("%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
_float32_unpack(c->q_min));
long maxcount=0,i,j;
for(i=0;i<bins;i++)
if(countarray[i]>maxcount)maxcount=countarray[i];
-
+
for(i=0;i<bins;i++){
int ptr=sort[i]-c->quantlist;
int stars=rint(50./maxcount*countarray[ptr]);
/* do it the simple way; two pass. */
line=setup_line(in);
- while(line){
+ while(line){
float code;
char buf[80];
lines++;
sprintf(buf,"getting min/max (%.2f::%.2f). lines...",min,max);
if(!(lines&0xff))spinnit(buf,lines);
-
+
while(!flag && sscanf(line,"%f",&code)==1){
line=strchr(line,',');
min=max=code;
flag=1;
}
-
+
while(line && sscanf(line,"%f",&code)==1){
line=strchr(line,',');
if(line)line++;
if(code<min)min=code;
if(code>max)max=code;
}
-
+
line=setup_line(in);
}
-
+
if(bins<1){
if((int)(max-min)==min-max){
bins=max-min;
bins=25;
}
}
-
+
printf("\r \r");
printf("Minimum scalar value: %f\n",min);
printf("Maximum scalar value: %f\n",max);
if(argv[2]){
-
+
printf("\n counting hits into %ld bins...\n",bins+1);
countarray=calloc(bins+1,sizeof(long));
-
+
rewind(in);
line=setup_line(in);
- while(line){
+ while(line){
float code;
lines--;
if(!(lines&0xff))spinnit("counting distribution. lines so far...",lines);
-
+
while(line && sscanf(line,"%f",&code)==1){
line=strchr(line,',');
if(line)line++;
-
+
code-=min;
code/=(max-min);
code*=bins;
countarray[(int)rint(code)]++;
total++;
}
-
+
line=setup_line(in);
}
-
+
/* make a pretty graph */
{
long maxcount=0,i,j;
for(i=0;i<bins+1;i++)
if(countarray[i]>maxcount)maxcount=countarray[i];
-
+
printf("\r \r");
printf("Total scalars: %ld\n",total);
for(i=0;i<bins+1;i++){
static void usage(){
fprintf(stderr,
- "usage:\n"
+ "usage:\n"
"huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
" where begin,n,group is first scalar, \n"
" number of scalars of each in line,\n"
long v;
if(get_next_ivalue(file,&v))break;
if(v>maxval)maxval=v;
-
+
if(!(i++&0xff))spinnit("loading... ",i);
}
rewind(file);
long vals=pow(maxval,subn);
long *hist=_ogg_calloc(vals,sizeof(long));
long *lengths=_ogg_calloc(vals,sizeof(long));
-
+
for(j=loval;j<vals;j++)hist[j]=guard;
-
+
if(file){
reset_next_value();
i/=subn;
}
fclose(file);
}
-
+
/* we have the probabilities, build the tree */
fprintf(stderr,"Building tree for %ld entries\n",vals);
build_tree_from_lengths0(vals,hist,lengths);
exit(1);
}
}
-
+
/* first, the static vectors, then the book structure to tie it together. */
/* lengthlist */
fprintf(file,"static const char _huff_lengthlist_%s[] = {\n",base);
fprintf(file,"\n");
}
fprintf(file,"};\n\n");
-
+
/* the toplevel book */
fprintf(file,"static const static_codebook _huff_book_%s = {\n",base);
fprintf(file,"\t%d, %ld,\n",subn,vals);
fprintf(file,"\tNULL,\n");
fprintf(file,"\t0\n};\n\n");
-
+
fclose(file);
fprintf(stderr,"Done. \n\n");
}
/* The purpose of this util is just to finish packaging the
description into a static codebook. It used to count hits for a
histogram, but I've divorced that out to add some flexibility (it
- currently generates an equal probability codebook)
+ currently generates an equal probability codebook)
command line:
latticebuild description.vql
<n> <dim> <multiplicitavep> <sequentialp>
<value_0> <value_1> <value_2> ... <value_n-1>
-
+
a threshmap (or pigeonmap) struct is generated by latticehint;
there are fun tricks one can do with the threshmap and cascades,
but the utils don't know them...
fprintf(stderr,"Could not open input file %s\n",filename);
exit(1);
}
-
+
ptr=strrchr(filename,'.');
if(ptr){
*ptr='\0';
}
}
-
+
/* read the description */
line=get_line(in);
if(sscanf(line,"%d %d %d %d",&quantvals,&dim,&addmul,&sequencep)!=4){
reset_next_value();
line=setup_line(in);
- for(j=0;j<quantvals;j++){
+ for(j=0;j<quantvals;j++){
char *temp;
if(!line || sscanf(line,"%lf",quantlist+j)!=1){
fprintf(stderr,"Ran out of data on line 2 of description file\n");
b=codebook_load(filename);
c=(static_codebook *)(b->c);
-
+
ptr=strrchr(filename,'.');
if(ptr){
*ptr='\0';
if(!strrcmp_i(argv[0],"latticetune")){
long lines=0;
line=setup_line(in);
- while(line){
+ while(line){
long code;
lines++;
if(!(lines&0xfff))spinnit("codewords so far...",lines);
-
+
if(sscanf(line,"%ld",&code)==1)
hits[code]++;
char *pos=strchr(line,':');
if(pos){
long code=atol(line);
- long val=atol(pos+1);
+ long val=atol(pos+1);
hits[code]+=val;
}
build_tree_from_lengths0(entries,hits,lengths);
c->lengthlist=lengths;
- write_codebook(stdout,name,c);
+ write_codebook(stdout,name,c);
{
long bins=_book_maptype1_quantvals(c);
long i,k,base=c->lengthlist[0];
for(i=0;i<entries;i++)
if(c->lengthlist[i]>base)base=c->lengthlist[i];
-
+
for(j=0;j<entries;j++){
if(c->lengthlist[j]){
int indexdiv=1;
fprintf(stderr,"%4ld: ",j);
- for(k=0;k<c->dim;k++){
+ for(k=0;k<c->dim;k++){
int index= (j/indexdiv)%bins;
fprintf(stderr,"%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
_float32_unpack(c->q_min));
}
}
}
-
+
fprintf(stderr,"\r "
"\nDone.\n");
exit(0);
/* collect the following metrics:
mean and mean squared amplitude
- mean and mean squared error
+ mean and mean squared error
mean and mean squared error (per sample) by entry
worst case fit by entry
entry cell size
total bits
total samples
(average bits per sample)*/
-
+
/* set up metrics */
void process_preprocess(codebook **bs,char *basename){
int i;
while(bs[books])books++;
-
+
if(books){
histogram=_ogg_calloc(books,sizeof(float *));
histogram_error=_ogg_calloc(books,sizeof(float *));
localmin=this;
}
}
-
+
if(min==-1 || localmin<min)min=localmin;
if(max==-1 || localmin>max)max=localmin;
mean+=sqrt(localmin);
total++;
}
}
-
+
fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
fprintf(stderr,"Could not open file %s for writing\n",buffer);
exit(1);
}
-
+
for(i=0;i<n;i++){
for(k=0;k<dim;k++){
fprintf(out,"%d, %g, %g\n",
}
}
fclose(out);
-
+
sprintf(buffer,"%s-%d-me.m",basename,book);
out=fopen(buffer,"w");
if(!out){
fprintf(stderr,"Could not open file %s for writing\n",buffer);
exit(1);
}
-
+
for(i=0;i<n;i++){
for(k=0;k<dim;k++){
fprintf(out,"%d, %g, %g\n",
fprintf(stderr,"Could not open file %s for writing\n",buffer);
exit(1);
}
-
+
for(i=0;i<n;i++){
for(k=0;k<dim;k++){
fprintf(out,"%d, %g, %g, %g\n",
fprintf(stderr,"Internal error: _best returned -1.\n");
exit(1);
}
-
- histogram[book][entry]++;
+
+ histogram[book][entry]++;
bits+=vorbis_book_codelen(b,entry);
-
+
for(j=0;j<dim;j++){
float error=a[j*step];
base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
}
}
-
+
if((long)(count)%100)spinnit("working.... samples: ",count);
}
* *
********************************************************************
- function: train a VQ codebook
+ function: train a VQ codebook
********************************************************************/
#include "vqgen.h"
#include "bookutil.h"
-/* Codebook generation happens in two steps:
+/* Codebook generation happens in two steps:
1) Train the codebook with data collected from the encoder: We use
one of a few error metrics (which represent the distance between a
given data point and a candidate point in the training set) to
divide the training set up into cells representing roughly equal
- probability of occurring.
+ probability of occurring.
2) Generate the codebook and auxiliary data from the trained data set
*/
if(this>0){
if(v->assigned[k] && (localmin==-1 || this<localmin))
localmin=this;
- }else{
+ }else{
if(k<j){
dup++;
break;
unused++;
continue;
}
-
+
localmin=v->max[j]+localmin/2; /* this gives us rough diameter */
if(min==-1 || localmin<min)min=localmin;
if(max==-1 || localmin>max)max=localmin;
for(i=0;i<count;i++)
fprintf(cells,"%g\n",spacings[i]);
fclose(cells);
-#endif
+#endif
}
int j,k;
mindel=maxdel=_now(v,0)[0];
-
+
for(j=0;j<v->entries;j++){
float last=0.f;
for(k=0;k<v->elements;k++){
for(k=0;k<v->elements;k++){
float val=_now(v,j)[k];
float now=rint((val-last-mindel)/delta);
-
+
_now(v,j)[k]=now;
if(now<0){
/* be paranoid; this should be impossible */
memcpy(_point(v,v->points),p,sizeof(float)*v->elements);
if(v->aux)memcpy(_point(v,v->points)+v->elements,a,sizeof(float)*v->aux);
-
+
/* quantize to the density mesh if it's selected */
if(v->mindist>0.f){
/* quantize to the mesh */
sprintf(buff,"bias%d.m",v->it);
bias=fopen(buff,"w");
#endif
-
+
if(v->entries<2){
fprintf(stderr,"generation requires at least two entries\n");
float secondmetric=v->metric_func(v,_now(v,1),ppt)+v->bias[1];
long firstentry=0;
long secondentry=1;
-
+
if(!(i&0xff))spinnit("biasing... ",v->points+v->points+v->entries-i);
-
+
if(firstmetric>secondmetric){
float temp=firstmetric;
firstmetric=secondmetric;
firstentry=1;
secondentry=0;
}
-
+
for(j=2;j<v->entries;j++){
float thismetric=v->metric_func(v,_now(v,j),ppt)+v->bias[j];
if(thismetric<secondmetric){
}
}
}
-
+
j=firstentry;
for(j=0;j<v->entries;j++){
-
+
float thismetric,localmetric;
float *nearbiasptr=nearbias+desired2*j;
long k=nearcount[j];
-
+
localmetric=v->metric_func(v,_now(v,j),ppt);
/* 'thismetric' is to be the bias value necessary in the current
arrangement for entry j to capture point i */
/* use the primary entry as the threshhold */
thismetric=firstmetric-localmetric;
}
-
+
/* support the idea of 'minimum distance'... if we want the
cells in a codebook to be roughly some minimum size (as with
the low resolution residue books) */
-
+
/* a cute two-stage delayed sorting hack */
if(k<desired){
nearbiasptr[k]=thismetric;
spinnit("biasing... ",v->points+v->points+v->entries-i);
qsort(nearbiasptr,desired,sizeof(float),directdsort);
}
-
+
}else if(thismetric>nearbiasptr[desired-1]){
nearbiasptr[k]=thismetric;
k++;
nearcount[j]=k;
}
}
-
+
/* inflate/deflate */
-
+
for(i=0;i<v->entries;i++){
float *nearbiasptr=nearbias+desired2*i;
-
+
spinnit("biasing... ",v->points+v->entries-i);
-
+
/* due to the delayed sorting, we likely need to finish it off....*/
if(nearcount[i]>desired)
qsort(nearbiasptr,nearcount[i],sizeof(float),directdsort);
v->bias[i]=nearbiasptr[desired-1];
}
- }else{
+ }else{
memset(v->bias,0,v->entries*sizeof(float));
}
}
j=firstentry;
-
+
#ifdef NOISY
fprintf(cells,"%g %g\n%g %g\n\n",
_now(v,j)[0],_now(v,j)[1],
fprintf(stderr,": dist %g(%g) metric error=%g \n",
asserror,fdesired,meterror/v->points);
v->it++;
-
+
free(new);
free(nearcount);
free(nearbias);