build.c 4.4 KB

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