diff options
Diffstat (limited to 'vq/residuesplit.c')
-rw-r--r-- | vq/residuesplit.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/vq/residuesplit.c b/vq/residuesplit.c new file mode 100644 index 00000000..126261f4 --- /dev/null +++ b/vq/residuesplit.c @@ -0,0 +1,240 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * + * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * + * PLEASE READ THESE TERMS DISTRIBUTING. * + * * + * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 * + * by Monty <monty@xiph.org> and The XIPHOPHORUS Company * + * http://www.xiph.org/ * + * * + ******************************************************************** + + function: residue backend 0 partitioner/classifier + last mod: $Id: residuesplit.c,v 1.3.4.1 2000/08/15 08:33:35 xiphmont Exp $ + + ********************************************************************/ + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <stdio.h> +#include "../vq/bookutil.h" +#include "../lib/sharedbook.h" + +/* does not guard against invalid settings; eg, a subn of 16 and a + subgroup request of 32. Max subn of 128 */ +static void _testhack(double *vec,int n,double *entropy){ + int i,j=0; + double max=0.; + double temp[128]; + + /* setup */ + for(i=0;i<n;i++)temp[i]=fabs(vec[i]); + + /* handle case subgrp==1 outside */ + for(i=0;i<n;i++) + if(temp[i]>max)max=temp[i]; + + for(i=0;i<n;i++)temp[i]=rint(temp[i]); + + while(1){ + entropy[j]=max; + n>>=1; + j++; + + if(n<=0)break; + for(i=0;i<n;i++){ + temp[i]+=temp[i+n]; + } + max=0.; + for(i=0;i<n;i++) + if(temp[i]>max)max=temp[i]; + } +} + +static FILE *of; +static FILE **or; + +/* we evaluate the the entropy measure for each interleaved subgroup */ +/* This is currently a bit specific to/hardwired for mapping 0; things + will need to change in the future when we get real multichannel + mappings */ +int quantaux(double *res,int n,double *ebound,double *mbound,int *subgrp,int parts, int subn){ + long i,j; + double entropy[8]; + int aux; + + for(i=0;i<=n-subn;i+=subn){ + double max=0.; + + _testhack(res+i,subn,entropy); + for(j=0;j<subn;j++) + if(fabs(res[i+j])>max)max=fabs(res[i+j]); + + for(j=0;j<parts-1;j++) + if(entropy[subgrp[j]]<=ebound[j] && + max<=mbound[j]) + break; + aux=j; + + fprintf(of,"%d, ",aux); + + for(j=0;j<subn;j++) + fprintf(or[aux],"%g, ",res[j+i]); + + fprintf(or[aux],"\n"); + } + + fprintf(of,"\n"); + + return(0); +} + +static int getline(FILE *in,double *vec,int begin,int n){ + int i,next=0; + + reset_next_value(); + if(get_next_value(in,vec))return(0); + if(begin){ + for(i=1;i<begin;i++) + get_line_value(in,vec); + next=0; + }else{ + next=1; + } + + for(i=next;i<n;i++) + if(get_line_value(in,vec+i)){ + fprintf(stderr,"ran out of columns in input data\n"); + exit(1); + } + + return(1); +} + +static void usage(){ + fprintf(stderr, + "usage:\n" + "residuesplit <res> <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n" + " where begin,n,group is first scalar, \n" + " number of scalars of each in line,\n" + " number of scalars in a group\n" + " ent is the maximum entropy value allowed for membership in a group\n" + " peak is the maximum amplitude value allowed for membership in a group\n" + " subn is the maximum entropy value allowed for membership in a group\n" + + "eg: residuesplit mask.vqd floor.vqd 0,1024,16 res 0,.5,16 3,1.5,8 \n" + "produces resaux.vqd and res_0...n.vqd\n\n"); + exit(1); +} + +int main(int argc, char *argv[]){ + char *buffer; + char *base; + int i,parts,begin,n,subn,*subgrp; + FILE *res; + double *ebound,*mbound,*vec; + long c=0; + if(argc<5)usage(); + + base=strdup(argv[3]); + buffer=alloca(strlen(base)+20); + { + char *pos=strchr(argv[2],','); + begin=atoi(argv[2]); + if(!pos) + usage(); + else + n=atoi(pos+1); + pos=strchr(pos+1,','); + if(!pos) + usage(); + else + subn=atoi(pos+1); + if(n/subn*subn != n){ + fprintf(stderr,"n must be divisible by group\n"); + exit(1); + } + } + + /* how many parts?... */ + parts=argc-3; + + ebound=malloc(sizeof(double)*parts); + mbound=malloc(sizeof(double)*parts); + subgrp=malloc(sizeof(int)*parts); + + for(i=0;i<parts-1;i++){ + char *pos=strchr(argv[4+i],','); + if(*argv[4+i]==',') + ebound[i]=1e50; + else + ebound[i]=atof(argv[4+i]); + + if(!pos){ + mbound[i]=1e50; + subgrp[i]=_ilog(subn)-1; + }else{ + if(*(pos+1)==',') + mbound[i]=1e50; + else + mbound[i]=atof(pos+1); + pos=strchr(pos+1,','); + + if(!pos){ + subgrp[i]=_ilog(subn)-1; + }else{ + subgrp[i]=_ilog(atoi(pos+1))-1; + } + } + } + + ebound[i]=1e50; + mbound[i]=1e50; + subgrp[i]=_ilog(subn)-1; + + res=fopen(argv[1],"r"); + if(!res){ + fprintf(stderr,"Could not open file %s\n",argv[1]); + exit(1); + } + + or=alloca(parts*sizeof(FILE*)); + sprintf(buffer,"%saux.vqd",base); + of=fopen(buffer,"w"); + if(!of){ + fprintf(stderr,"Could not open file %s for writing\n",buffer); + exit(1); + } + for(i=0;i<parts;i++){ + sprintf(buffer,"%s_%d.vqd",base,i); + or[i]=fopen(buffer,"w"); + if(!or[i]){ + fprintf(stderr,"Could not open file %s for writing\n",buffer); + exit(1); + } + } + + vec=malloc(sizeof(double)*n); + /* get the input line by line and process it */ + while(!feof(res)){ + if(getline(res,vec,begin,n)) + quantaux(vec,n,ebound,mbound,subgrp,parts,subn); + c++; + if(!(c&0xf)){ + spinnit("kB so far...",(int)(ftell(res)/1024)); + } + } + fclose(res); + fclose(of); + for(i=0;i<parts;i++) + fclose(or[i]); + fprintf(stderr,"\rDone \n"); + return(0); +} + + + + |