1/******************************************************************** 2 * * 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 * * 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * 9 * by the Xiph.Org Foundation http://www.xiph.org/ * 10 * * 11 ******************************************************************** 12 13 function: residue backend 0 partitioner/classifier 14 last mod: $Id: residuesplit.c 16037 2009-05-26 21:10:58Z xiphmont $ 15 16 ********************************************************************/ 17 18#include <stdlib.h> 19#include <string.h> 20#include <math.h> 21#include <stdio.h> 22#include "bookutil.h" 23 24/* does not guard against invalid settings; eg, a subn of 16 and a 25 subgroup request of 32. Max subn of 128 */ 26static float _testhack(float *vec,int n){ 27 int i,j=0; 28 float max=0.f; 29 float temp[128]; 30 float entropy=0.; 31 32 /* setup */ 33 for(i=0;i<n;i++)temp[i]=fabs(vec[i]); 34 35 /* handle case subgrp==1 outside */ 36 for(i=0;i<n;i++) 37 if(temp[i]>max)max=temp[i]; 38 39 for(i=0;i<n;i++)temp[i]=rint(temp[i]); 40 41 for(i=0;i<n;i++) 42 entropy+=temp[i]; 43 return entropy; 44 45 /*while(1){ 46 entropy[j]=max; 47 n>>=1; 48 j++; 49 50 if(n<=0)break; 51 for(i=0;i<n;i++){ 52 temp[i]+=temp[i+n]; 53 } 54 max=0.f; 55 for(i=0;i<n;i++) 56 if(temp[i]>max)max=temp[i]; 57 }*/ 58} 59 60static FILE *of; 61static FILE **or; 62 63/* we evaluate the the entropy measure for each interleaved subgroup */ 64/* This is currently a bit specific to/hardwired for mapping 0; things 65 will need to change in the future when we get real multichannel 66 mappings */ 67int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn, 68 int *class){ 69 long i,j,part=0; 70 int aux; 71 72 for(i=0;i<=n-subn;i+=subn,part++){ 73 float max=0.f; 74 float lentropy=0.f; 75 76 lentropy=_testhack(res+i,subn); 77 78 for(j=0;j<subn;j++) 79 if(fabs(res[i+j])>max)max=fabs(res[i+j]); 80 81 for(j=0;j<parts-1;j++) 82 if(lentropy<=ebound[j] && 83 max<=mbound[j] && 84 part<subgrp[j]) 85 break; 86 class[part]=aux=j; 87 88 fprintf(of,"%d, ",aux); 89 } 90 fprintf(of,"\n"); 91 92 return(0); 93} 94 95int quantwrite(float *res,int n,int subn, int *class,int offset){ 96 long i,j,part=0; 97 int aux; 98 99 for(i=0;i<=n-subn;i+=subn,part++){ 100 aux=class[part]; 101 102 for(j=0;j<subn;j++) 103 fprintf(or[aux+offset],"%g, ",res[j+i]); 104 105 fprintf(or[aux+offset],"\n"); 106 } 107 108 return(0); 109} 110 111static int getline(FILE *in,float *vec,int begin,int n){ 112 int i,next=0; 113 114 reset_next_value(); 115 if(get_next_value(in,vec))return(0); 116 if(begin){ 117 for(i=1;i<begin;i++) 118 get_line_value(in,vec); 119 next=0; 120 }else{ 121 next=1; 122 } 123 124 for(i=next;i<n;i++) 125 if(get_line_value(in,vec+i)){ 126 fprintf(stderr,"ran out of columns in input data\n"); 127 exit(1); 128 } 129 130 return(1); 131} 132 133static void usage(){ 134 fprintf(stderr, 135 "usage:\n" 136 "residuesplit <res> [<res>] <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n" 137 " where begin,n,group is first scalar, \n" 138 " number of scalars of each in line,\n" 139 " number of scalars in a group\n" 140 " ent is the maximum entropy value allowed for membership in a group\n" 141 " peak is the maximum amplitude value allowed for membership in a group\n" 142 " subn is the maximum subpartiton number allowed in the group\n\n"); 143 exit(1); 144} 145 146int main(int argc, char *argv[]){ 147 char *buffer; 148 char *base; 149 int i,j,parts,begin,n,subn,*subgrp,*class; 150 FILE **res; 151 int resfiles=0; 152 float *ebound,*mbound,*vec; 153 long c=0; 154 if(argc<5)usage(); 155 156 /* count the res file names, open the files */ 157 while(!strcmp(argv[resfiles+1]+strlen(argv[resfiles+1])-4,".vqd")) 158 resfiles++; 159 if(resfiles<1)usage(); 160 161 res=alloca(sizeof(*res)*resfiles); 162 for(i=0;i<resfiles;i++){ 163 res[i]=fopen(argv[i+1],"r"); 164 if(!(res+i)){ 165 fprintf(stderr,"Could not open file %s\n",argv[1+i]); 166 exit(1); 167 } 168 } 169 170 base=strdup(argv[2+resfiles]); 171 buffer=alloca(strlen(base)+20); 172 { 173 char *pos=strchr(argv[1+resfiles],','); 174 begin=atoi(argv[1+resfiles]); 175 if(!pos) 176 usage(); 177 else 178 n=atoi(pos+1); 179 pos=strchr(pos+1,','); 180 if(!pos) 181 usage(); 182 else 183 subn=atoi(pos+1); 184 if(n/subn*subn != n){ 185 fprintf(stderr,"n must be divisible by group\n"); 186 exit(1); 187 } 188 } 189 190 /* how many parts?... */ 191 parts=argc-resfiles-2; 192 193 ebound=_ogg_malloc(sizeof(float)*parts); 194 mbound=_ogg_malloc(sizeof(float)*parts); 195 subgrp=_ogg_malloc(sizeof(int)*parts); 196 197 for(i=0;i<parts-1;i++){ 198 char *pos=strchr(argv[3+i+resfiles],','); 199 subgrp[i]=0; 200 if(*argv[3+i+resfiles]==',') 201 ebound[i]=1e50f; 202 else 203 ebound[i]=atof(argv[3+i+resfiles]); 204 205 if(!pos){ 206 mbound[i]=1e50f; 207 }else{ 208 if(*(pos+1)==',') 209 mbound[i]=1e50f; 210 else 211 mbound[i]=atof(pos+1); 212 pos=strchr(pos+1,','); 213 214 if(pos) 215 subgrp[i]=atoi(pos+1); 216 217 } 218 if(subgrp[i]<=0)subgrp[i]=99999; 219 } 220 221 ebound[i]=1e50f; 222 mbound[i]=1e50f; 223 subgrp[i]=9999999; 224 225 or=alloca(parts*resfiles*sizeof(FILE*)); 226 sprintf(buffer,"%saux.vqd",base); 227 of=fopen(buffer,"w"); 228 if(!of){ 229 fprintf(stderr,"Could not open file %s for writing\n",buffer); 230 exit(1); 231 } 232 233 for(j=0;j<resfiles;j++){ 234 for(i=0;i<parts;i++){ 235 sprintf(buffer,"%s_%d%c.vqd",base,i,j+65); 236 or[i+j*parts]=fopen(buffer,"w"); 237 if(!or[i+j*parts]){ 238 fprintf(stderr,"Could not open file %s for writing\n",buffer); 239 exit(1); 240 } 241 } 242 } 243 244 vec=_ogg_malloc(sizeof(float)*n); 245 class=_ogg_malloc(sizeof(float)*n); 246 /* get the input line by line and process it */ 247 while(1){ 248 if(getline(res[0],vec,begin,n)){ 249 quantaux(vec,n,ebound,mbound,subgrp,parts,subn,class); 250 quantwrite(vec,n,subn,class,0); 251 252 for(i=1;i<resfiles;i++){ 253 if(getline(res[i],vec,begin,n)){ 254 quantwrite(vec,n,subn,class,parts*i); 255 }else{ 256 fprintf(stderr,"Getline loss of sync (%d).\n\n",i); 257 exit(1); 258 } 259 } 260 }else{ 261 if(feof(res[0]))break; 262 fprintf(stderr,"Getline loss of sync (0).\n\n"); 263 exit(1); 264 } 265 266 c++; 267 if(!(c&0xf)){ 268 spinnit("kB so far...",(int)(ftell(res[0])/1024)); 269 } 270 } 271 for(i=0;i<resfiles;i++) 272 fclose(res[i]); 273 fclose(of); 274 for(i=0;i<parts*resfiles;i++) 275 fclose(or[i]); 276 fprintf(stderr,"\rDone \n"); 277 return(0); 278} 279 280 281 282 283