build.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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: utility main for building codebooks from training sets
  13. last mod: $Id$
  14. ********************************************************************/
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <math.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include "bookutil.h"
  21. #include "vqgen.h"
  22. #include "vqsplit.h"
  23. static char *linebuffer=NULL;
  24. static int lbufsize=0;
  25. static char *rline(FILE *in,FILE *out){
  26. long sofar=0;
  27. if(feof(in))return NULL;
  28. while(1){
  29. int gotline=0;
  30. while(!gotline){
  31. if(sofar>=lbufsize){
  32. if(!lbufsize){
  33. lbufsize=1024;
  34. linebuffer=_ogg_malloc(lbufsize);
  35. }else{
  36. lbufsize*=2;
  37. linebuffer=_ogg_realloc(linebuffer,lbufsize);
  38. }
  39. }
  40. {
  41. long c=fgetc(in);
  42. switch(c){
  43. case '\n':
  44. case EOF:
  45. gotline=1;
  46. break;
  47. default:
  48. linebuffer[sofar++]=c;
  49. linebuffer[sofar]='\0';
  50. break;
  51. }
  52. }
  53. }
  54. if(linebuffer[0]=='#'){
  55. sofar=0;
  56. }else{
  57. return(linebuffer);
  58. }
  59. }
  60. }
  61. /* command line:
  62. buildvq file
  63. */
  64. int main(int argc,char *argv[]){
  65. vqgen v;
  66. static_codebook c;
  67. codebook b;
  68. quant_meta q;
  69. long *quantlist=NULL;
  70. int entries=-1,dim=-1,aux=-1;
  71. FILE *out=NULL;
  72. FILE *in=NULL;
  73. char *line,*name;
  74. long i,j,k;
  75. b.c=&c;
  76. if(argv[1]==NULL){
  77. fprintf(stderr,"Need a trained data set on the command line.\n");
  78. exit(1);
  79. }
  80. {
  81. char *ptr;
  82. char *filename=strdup(argv[1]);
  83. in=fopen(filename,"r");
  84. if(!in){
  85. fprintf(stderr,"Could not open input file %s\n",filename);
  86. exit(1);
  87. }
  88. ptr=strrchr(filename,'-');
  89. if(ptr){
  90. *ptr='\0';
  91. name=strdup(filename);
  92. sprintf(ptr,".vqh");
  93. }else{
  94. name=strdup(filename);
  95. strcat(filename,".vqh");
  96. }
  97. out=fopen(filename,"w");
  98. if(out==NULL){
  99. fprintf(stderr,"Unable to open %s for writing\n",filename);
  100. exit(1);
  101. }
  102. }
  103. /* suck in the trained book */
  104. /* read book type, but it doesn't matter */
  105. line=rline(in,out);
  106. line=rline(in,out);
  107. if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){
  108. fprintf(stderr,"Syntax error reading book file\n");
  109. exit(1);
  110. }
  111. /* just use it to allocate mem */
  112. vqgen_init(&v,dim,0,entries,0.f,NULL,NULL,0);
  113. /* quant */
  114. line=rline(in,out);
  115. if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
  116. &q.quant,&q.sequencep)!=4){
  117. fprintf(stderr,"Syntax error reading book file\n");
  118. exit(1);
  119. }
  120. /* quantized entries */
  121. /* save quant data; we don't want to requantize later as our method
  122. is currently imperfect wrt repeated application */
  123. i=0;
  124. quantlist=_ogg_malloc(sizeof(long)*v.elements*v.entries);
  125. for(j=0;j<entries;j++){
  126. float a;
  127. for(k=0;k<dim;k++){
  128. line=rline(in,out);
  129. sscanf(line,"%f",&a);
  130. v.entrylist[i]=a;
  131. quantlist[i++]=rint(a);
  132. }
  133. }
  134. /* ignore bias */
  135. for(j=0;j<entries;j++)line=rline(in,out);
  136. free(v.bias);
  137. v.bias=NULL;
  138. /* training points */
  139. {
  140. float *b=alloca(sizeof(float)*(dim+aux));
  141. i=0;
  142. v.entries=0; /* hack to avoid reseeding */
  143. while(1){
  144. for(k=0;k<dim+aux;k++){
  145. line=rline(in,out);
  146. if(!line)break;
  147. sscanf(line,"%f",b+k);
  148. }
  149. if(feof(in))break;
  150. vqgen_addpoint(&v,b,NULL);
  151. }
  152. v.entries=entries;
  153. }
  154. fclose(in);
  155. vqgen_unquantize(&v,&q);
  156. /* build the book */
  157. vqsp_book(&v,&b,quantlist);
  158. c.q_min=q.min;
  159. c.q_delta=q.delta;
  160. c.q_quant=q.quant;
  161. c.q_sequencep=q.sequencep;
  162. /* save the book in C header form */
  163. write_codebook(out,name,b.c);
  164. fclose(out);
  165. exit(0);
  166. }