bookutil.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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-2010 *
  9. * by the Xiph.Org Foundation http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: utility functions for loading .vqh and .vqd files
  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. int _best(codebook *book, float *a, int step){
  22. int dim=book->dim;
  23. int i,j,o;
  24. int minval=book->minval;
  25. int del=book->delta;
  26. int qv=book->quantvals;
  27. int ze=(qv>>1);
  28. int index=0;
  29. /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
  30. if(del!=1){
  31. for(i=0,o=step*(dim-1);i<dim;i++,o-=step){
  32. int v = ((int)rint(a[o])-minval+(del>>1))/del;
  33. int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
  34. index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
  35. }
  36. }else{
  37. for(i=0,o=step*(dim-1);i<dim;i++,o-=step){
  38. int v = (int)rint(a[o])-minval;
  39. int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
  40. index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
  41. }
  42. }
  43. if(book->c->lengthlist[index]<=0){
  44. const static_codebook *c=book->c;
  45. int best=-1;
  46. /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
  47. int e[8]={0,0,0,0,0,0,0,0};
  48. int maxval = book->minval + book->delta*(book->quantvals-1);
  49. for(i=0;i<book->entries;i++){
  50. if(c->lengthlist[i]>0){
  51. float this=0;
  52. for(j=0;j<dim;j++){
  53. float val=(e[j]-a[j*step]);
  54. this+=val*val;
  55. }
  56. if(best==-1 || this<best){
  57. best=this;
  58. index=i;
  59. }
  60. }
  61. /* assumes the value patterning created by the tools in vq/ */
  62. j=0;
  63. while(e[j]>=maxval)
  64. e[j++]=0;
  65. if(e[j]>=0)
  66. e[j]+=book->delta;
  67. e[j]= -e[j];
  68. }
  69. }
  70. return index;
  71. }
  72. /* A few little utils for reading files */
  73. /* read a line. Use global, persistent buffering */
  74. static char *linebuffer=NULL;
  75. static int lbufsize=0;
  76. char *get_line(FILE *in){
  77. long sofar=0;
  78. if(feof(in))return NULL;
  79. while(1){
  80. int gotline=0;
  81. while(!gotline){
  82. if(sofar+1>=lbufsize){
  83. if(!lbufsize){
  84. lbufsize=1024;
  85. linebuffer=_ogg_malloc(lbufsize);
  86. }else{
  87. lbufsize*=2;
  88. linebuffer=_ogg_realloc(linebuffer,lbufsize);
  89. }
  90. }
  91. {
  92. long c=fgetc(in);
  93. switch(c){
  94. case EOF:
  95. if(sofar==0)return(NULL);
  96. /* fallthrough correct */
  97. case '\n':
  98. linebuffer[sofar]='\0';
  99. gotline=1;
  100. break;
  101. default:
  102. linebuffer[sofar++]=c;
  103. linebuffer[sofar]='\0';
  104. break;
  105. }
  106. }
  107. }
  108. if(linebuffer[0]=='#'){
  109. sofar=0;
  110. }else{
  111. return(linebuffer);
  112. }
  113. }
  114. }
  115. /* read the next numerical value from the given file */
  116. static char *value_line_buff=NULL;
  117. int get_line_value(FILE *in,float *value){
  118. char *next;
  119. if(!value_line_buff)return(-1);
  120. *value=strtod(value_line_buff, &next);
  121. if(next==value_line_buff){
  122. value_line_buff=NULL;
  123. return(-1);
  124. }else{
  125. value_line_buff=next;
  126. while(*value_line_buff>44)value_line_buff++;
  127. if(*value_line_buff==44)value_line_buff++;
  128. return(0);
  129. }
  130. }
  131. int get_next_value(FILE *in,float *value){
  132. while(1){
  133. if(get_line_value(in,value)){
  134. value_line_buff=get_line(in);
  135. if(!value_line_buff)return(-1);
  136. }else{
  137. return(0);
  138. }
  139. }
  140. }
  141. int get_next_ivalue(FILE *in,long *ivalue){
  142. float value;
  143. int ret=get_next_value(in,&value);
  144. *ivalue=value;
  145. return(ret);
  146. }
  147. static float sequence_base=0.f;
  148. static int v_sofar=0;
  149. void reset_next_value(void){
  150. value_line_buff=NULL;
  151. sequence_base=0.f;
  152. v_sofar=0;
  153. }
  154. char *setup_line(FILE *in){
  155. reset_next_value();
  156. value_line_buff=get_line(in);
  157. return(value_line_buff);
  158. }
  159. int get_vector(codebook *b,FILE *in,int start, int n,float *a){
  160. int i;
  161. const static_codebook *c=b->c;
  162. while(1){
  163. if(v_sofar==n || get_line_value(in,a)){
  164. reset_next_value();
  165. if(get_next_value(in,a))
  166. break;
  167. for(i=0;i<start;i++){
  168. sequence_base=*a;
  169. get_line_value(in,a);
  170. }
  171. }
  172. for(i=1;i<c->dim;i++)
  173. if(get_line_value(in,a+i))
  174. break;
  175. if(i==c->dim){
  176. float temp=a[c->dim-1];
  177. for(i=0;i<c->dim;i++)a[i]-=sequence_base;
  178. if(c->q_sequencep)sequence_base=temp;
  179. v_sofar++;
  180. return(0);
  181. }
  182. sequence_base=0.f;
  183. }
  184. return(-1);
  185. }
  186. /* read lines fromt he beginning until we find one containing the
  187. specified string */
  188. char *find_seek_to(FILE *in,char *s){
  189. rewind(in);
  190. while(1){
  191. char *line=get_line(in);
  192. if(line){
  193. if(strstr(line,s))
  194. return(line);
  195. }else
  196. return(NULL);
  197. }
  198. }
  199. /* this reads the format as written by vqbuild/latticebuild; innocent
  200. (legal) tweaking of the file that would not affect its valid
  201. header-ness will break this routine */
  202. codebook *codebook_load(char *filename){
  203. codebook *b=_ogg_calloc(1,sizeof(codebook));
  204. static_codebook *c=(static_codebook *)(b->c=_ogg_calloc(1,sizeof(static_codebook)));
  205. int quant_to_read=0;
  206. FILE *in=fopen(filename,"r");
  207. char *line;
  208. long i;
  209. if(in==NULL){
  210. fprintf(stderr,"Couldn't open codebook %s\n",filename);
  211. exit(1);
  212. }
  213. /* find the codebook struct */
  214. find_seek_to(in,"static const static_codebook ");
  215. /* get the major important values */
  216. line=get_line(in);
  217. if(sscanf(line,"%ld, %ld,",
  218. &(c->dim),&(c->entries))!=2){
  219. fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
  220. exit(1);
  221. }
  222. line=get_line(in);
  223. line=get_line(in);
  224. if(sscanf(line,"%d, %ld, %ld, %d, %d,",
  225. &(c->maptype),&(c->q_min),&(c->q_delta),&(c->q_quant),
  226. &(c->q_sequencep))!=5){
  227. fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
  228. exit(1);
  229. }
  230. switch(c->maptype){
  231. case 0:
  232. quant_to_read=0;
  233. break;
  234. case 1:
  235. quant_to_read=_book_maptype1_quantvals(c);
  236. break;
  237. case 2:
  238. quant_to_read=c->entries*c->dim;
  239. break;
  240. }
  241. /* load the quantized entries */
  242. find_seek_to(in,"static const long _vq_quantlist_");
  243. reset_next_value();
  244. c->quantlist=_ogg_malloc(sizeof(long)*quant_to_read);
  245. for(i=0;i<quant_to_read;i++)
  246. if(get_next_ivalue(in,c->quantlist+i)){
  247. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  248. exit(1);
  249. }
  250. /* load the lengthlist */
  251. find_seek_to(in,"_lengthlist");
  252. reset_next_value();
  253. c->lengthlist=_ogg_malloc(sizeof(long)*c->entries);
  254. for(i=0;i<c->entries;i++)
  255. if(get_next_ivalue(in,c->lengthlist+i)){
  256. fprintf(stderr,"out of data while reading codebook %s\n",filename);
  257. exit(1);
  258. }
  259. /* got it all */
  260. fclose(in);
  261. vorbis_book_init_encode(b,c);
  262. b->valuelist=_book_unquantize(c,c->entries,NULL);
  263. return(b);
  264. }
  265. void spinnit(char *s,int n){
  266. static int p=0;
  267. static long lasttime=0;
  268. long test;
  269. struct timeval thistime;
  270. gettimeofday(&thistime,NULL);
  271. test=thistime.tv_sec*10+thistime.tv_usec/100000;
  272. if(lasttime!=test){
  273. lasttime=test;
  274. fprintf(stderr,"%s%d ",s,n);
  275. p++;if(p>3)p=0;
  276. switch(p){
  277. case 0:
  278. fprintf(stderr,"| \r");
  279. break;
  280. case 1:
  281. fprintf(stderr,"/ \r");
  282. break;
  283. case 2:
  284. fprintf(stderr,"- \r");
  285. break;
  286. case 3:
  287. fprintf(stderr,"\\ \r");
  288. break;
  289. }
  290. fflush(stderr);
  291. }
  292. }
  293. void build_tree_from_lengths(int vals, long *hist, long *lengths){
  294. int i,j;
  295. long *membership=_ogg_malloc(vals*sizeof(long));
  296. long *histsave=alloca(vals*sizeof(long));
  297. memcpy(histsave,hist,vals*sizeof(long));
  298. for(i=0;i<vals;i++)membership[i]=i;
  299. /* find codeword lengths */
  300. /* much more elegant means exist. Brute force n^2, minimum thought */
  301. for(i=vals;i>1;i--){
  302. int first=-1,second=-1;
  303. long least=-1;
  304. spinnit("building... ",i);
  305. /* find the two nodes to join */
  306. for(j=0;j<vals;j++)
  307. if(least==-1 || hist[j]<=least){
  308. least=hist[j];
  309. first=membership[j];
  310. }
  311. least=-1;
  312. for(j=0;j<vals;j++)
  313. if((least==-1 || hist[j]<=least) && membership[j]!=first){
  314. least=hist[j];
  315. second=membership[j];
  316. }
  317. if(first==-1 || second==-1){
  318. fprintf(stderr,"huffman fault; no free branch\n");
  319. exit(1);
  320. }
  321. /* join them */
  322. least=hist[first]+hist[second];
  323. for(j=0;j<vals;j++)
  324. if(membership[j]==first || membership[j]==second){
  325. membership[j]=first;
  326. hist[j]=least;
  327. lengths[j]++;
  328. }
  329. }
  330. for(i=0;i<vals-1;i++)
  331. if(membership[i]!=membership[i+1]){
  332. fprintf(stderr,"huffman fault; failed to build single tree\n");
  333. exit(1);
  334. }
  335. /* for sanity check purposes: how many bits would it have taken to
  336. encode the training set? */
  337. {
  338. long bitsum=0;
  339. long samples=0;
  340. for(i=0;i<vals;i++){
  341. bitsum+=(histsave[i]-1)*lengths[i];
  342. samples+=histsave[i]-1;
  343. }
  344. if(samples){
  345. fprintf(stderr,"\rTotal samples in training set: %ld \n",samples);
  346. fprintf(stderr,"\rTotal bits used to represent training set: %ld\n",
  347. bitsum);
  348. }
  349. }
  350. free(membership);
  351. }
  352. /* wrap build_tree_from_lengths to allow zero entries in the histogram */
  353. void build_tree_from_lengths0(int vals, long *hist, long *lengths){
  354. /* pack the 'sparse' hit list into a dense list, then unpack
  355. the lengths after the build */
  356. int upper=0,i;
  357. long *lengthlist=_ogg_calloc(vals,sizeof(long));
  358. long *newhist=alloca(vals*sizeof(long));
  359. for(i=0;i<vals;i++)
  360. if(hist[i]>0)
  361. newhist[upper++]=hist[i];
  362. if(upper != vals){
  363. fprintf(stderr,"\rEliminating %d unused entries; %d entries remain\n",
  364. vals-upper,upper);
  365. }
  366. build_tree_from_lengths(upper,newhist,lengthlist);
  367. upper=0;
  368. for(i=0;i<vals;i++)
  369. if(hist[i]>0)
  370. lengths[i]=lengthlist[upper++];
  371. else
  372. lengths[i]=0;
  373. free(lengthlist);
  374. }
  375. void write_codebook(FILE *out,char *name,const static_codebook *c){
  376. int i,j,k;
  377. /* save the book in C header form */
  378. /* first, the static vectors, then the book structure to tie it together. */
  379. /* quantlist */
  380. if(c->quantlist){
  381. long vals=(c->maptype==1?_book_maptype1_quantvals(c):c->entries*c->dim);
  382. fprintf(out,"static const long _vq_quantlist_%s[] = {\n",name);
  383. for(j=0;j<vals;j++){
  384. fprintf(out,"\t%ld,\n",c->quantlist[j]);
  385. }
  386. fprintf(out,"};\n\n");
  387. }
  388. /* lengthlist */
  389. fprintf(out,"static const long _vq_lengthlist_%s[] = {\n",name);
  390. for(j=0;j<c->entries;){
  391. fprintf(out,"\t");
  392. for(k=0;k<16 && j<c->entries;k++,j++)
  393. fprintf(out,"%2ld,",c->lengthlist[j]);
  394. fprintf(out,"\n");
  395. }
  396. fprintf(out,"};\n\n");
  397. /* tie it all together */
  398. fprintf(out,"static const static_codebook %s = {\n",name);
  399. fprintf(out,"\t%ld, %ld,\n",c->dim,c->entries);
  400. fprintf(out,"\t(long *)_vq_lengthlist_%s,\n",name);
  401. fprintf(out,"\t%d, %ld, %ld, %d, %d,\n",
  402. c->maptype,c->q_min,c->q_delta,c->q_quant,c->q_sequencep);
  403. if(c->quantlist)
  404. fprintf(out,"\t(long *)_vq_quantlist_%s,\n",name);
  405. else
  406. fprintf(out,"\tNULL,\n");
  407. fprintf(out,"\t0\n};\n\n");
  408. }