bookutil.c 12 KB

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