residuesplit.c 6.8 KB

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