residuesplit.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
  6. * PLEASE READ THESE TERMS DISTRIBUTING. *
  7. * *
  8. * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
  9. * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
  10. * http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: residue backend 0 partitioner/classifier
  14. last mod: $Id: residuesplit.c,v 1.4.2.1 2000/08/31 08:59:58 xiphmont Exp $
  15. ********************************************************************/
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include "../vq/bookutil.h"
  21. #include "../lib/sharedbook.h"
  22. /* does not guard against invalid settings; eg, a subn of 16 and a
  23. subgroup request of 32. Max subn of 128 */
  24. static void _testhack(float *vec,int n,float *entropy){
  25. int i,j=0;
  26. float max=0.;
  27. float temp[128];
  28. /* setup */
  29. for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
  30. /* handle case subgrp==1 outside */
  31. for(i=0;i<n;i++)
  32. if(temp[i]>max)max=temp[i];
  33. for(i=0;i<n;i++)temp[i]=rint(temp[i]);
  34. while(1){
  35. entropy[j]=max;
  36. n>>=1;
  37. j++;
  38. if(n<=0)break;
  39. for(i=0;i<n;i++){
  40. temp[i]+=temp[i+n];
  41. }
  42. max=0.;
  43. for(i=0;i<n;i++)
  44. if(temp[i]>max)max=temp[i];
  45. }
  46. }
  47. static FILE *of;
  48. static FILE **or;
  49. /* we evaluate the the entropy measure for each interleaved subgroup */
  50. /* This is currently a bit specific to/hardwired for mapping 0; things
  51. will need to change in the future when we get real multichannel
  52. mappings */
  53. int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn){
  54. long i,j;
  55. float entropy[8];
  56. int aux;
  57. for(i=0;i<=n-subn;i+=subn){
  58. float max=0.;
  59. _testhack(res+i,subn,entropy);
  60. for(j=0;j<subn;j++)
  61. if(fabs(res[i+j])>max)max=fabs(res[i+j]);
  62. for(j=0;j<parts-1;j++)
  63. if(entropy[subgrp[j]]<=ebound[j] &&
  64. max<=mbound[j])
  65. break;
  66. aux=j;
  67. fprintf(of,"%d, ",aux);
  68. for(j=0;j<subn;j++)
  69. fprintf(or[aux],"%g, ",res[j+i]);
  70. fprintf(or[aux],"\n");
  71. }
  72. fprintf(of,"\n");
  73. return(0);
  74. }
  75. static int getline(FILE *in,float *vec,int begin,int n){
  76. int i,next=0;
  77. reset_next_value();
  78. if(get_next_value(in,vec))return(0);
  79. if(begin){
  80. for(i=1;i<begin;i++)
  81. get_line_value(in,vec);
  82. next=0;
  83. }else{
  84. next=1;
  85. }
  86. for(i=next;i<n;i++)
  87. if(get_line_value(in,vec+i)){
  88. fprintf(stderr,"ran out of columns in input data\n");
  89. exit(1);
  90. }
  91. return(1);
  92. }
  93. static void usage(){
  94. fprintf(stderr,
  95. "usage:\n"
  96. "residuesplit <res> <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
  97. " where begin,n,group is first scalar, \n"
  98. " number of scalars of each in line,\n"
  99. " number of scalars in a group\n"
  100. " ent is the maximum entropy value allowed for membership in a group\n"
  101. " peak is the maximum amplitude value allowed for membership in a group\n"
  102. " subn is the maximum entropy value allowed for membership in a group\n"
  103. "eg: residuesplit mask.vqd floor.vqd 0,1024,16 res 0,.5,16 3,1.5,8 \n"
  104. "produces resaux.vqd and res_0...n.vqd\n\n");
  105. exit(1);
  106. }
  107. int main(int argc, char *argv[]){
  108. char *buffer;
  109. char *base;
  110. int i,parts,begin,n,subn,*subgrp;
  111. FILE *res;
  112. float *ebound,*mbound,*vec;
  113. long c=0;
  114. if(argc<5)usage();
  115. base=strdup(argv[3]);
  116. buffer=alloca(strlen(base)+20);
  117. {
  118. char *pos=strchr(argv[2],',');
  119. begin=atoi(argv[2]);
  120. if(!pos)
  121. usage();
  122. else
  123. n=atoi(pos+1);
  124. pos=strchr(pos+1,',');
  125. if(!pos)
  126. usage();
  127. else
  128. subn=atoi(pos+1);
  129. if(n/subn*subn != n){
  130. fprintf(stderr,"n must be divisible by group\n");
  131. exit(1);
  132. }
  133. }
  134. /* how many parts?... */
  135. parts=argc-3;
  136. ebound=malloc(sizeof(float)*parts);
  137. mbound=malloc(sizeof(float)*parts);
  138. subgrp=malloc(sizeof(int)*parts);
  139. for(i=0;i<parts-1;i++){
  140. char *pos=strchr(argv[4+i],',');
  141. if(*argv[4+i]==',')
  142. ebound[i]=1e50;
  143. else
  144. ebound[i]=atof(argv[4+i]);
  145. if(!pos){
  146. mbound[i]=1e50;
  147. subgrp[i]=_ilog(subn)-1;
  148. }else{
  149. if(*(pos+1)==',')
  150. mbound[i]=1e50;
  151. else
  152. mbound[i]=atof(pos+1);
  153. pos=strchr(pos+1,',');
  154. if(!pos){
  155. subgrp[i]=_ilog(subn)-1;
  156. }else{
  157. subgrp[i]=_ilog(atoi(pos+1))-1;
  158. }
  159. }
  160. }
  161. ebound[i]=1e50;
  162. mbound[i]=1e50;
  163. subgrp[i]=_ilog(subn)-1;
  164. res=fopen(argv[1],"r");
  165. if(!res){
  166. fprintf(stderr,"Could not open file %s\n",argv[1]);
  167. exit(1);
  168. }
  169. or=alloca(parts*sizeof(FILE*));
  170. sprintf(buffer,"%saux.vqd",base);
  171. of=fopen(buffer,"w");
  172. if(!of){
  173. fprintf(stderr,"Could not open file %s for writing\n",buffer);
  174. exit(1);
  175. }
  176. for(i=0;i<parts;i++){
  177. sprintf(buffer,"%s_%d.vqd",base,i);
  178. or[i]=fopen(buffer,"w");
  179. if(!or[i]){
  180. fprintf(stderr,"Could not open file %s for writing\n",buffer);
  181. exit(1);
  182. }
  183. }
  184. vec=malloc(sizeof(float)*n);
  185. /* get the input line by line and process it */
  186. while(!feof(res)){
  187. if(getline(res,vec,begin,n))
  188. quantaux(vec,n,ebound,mbound,subgrp,parts,subn);
  189. c++;
  190. if(!(c&0xf)){
  191. spinnit("kB so far...",(int)(ftell(res)/1024));
  192. }
  193. }
  194. fclose(res);
  195. fclose(of);
  196. for(i=0;i<parts;i++)
  197. fclose(or[i]);
  198. fprintf(stderr,"\rDone \n");
  199. return(0);
  200. }