residuedata.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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: metrics and quantization code for residue VQ codebooks
  13. last mod: $Id$
  14. ********************************************************************/
  15. #include <stdlib.h>
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include "vqgen.h"
  20. #include "bookutil.h"
  21. #include "../lib/scales.h"
  22. #include "vqext.h"
  23. float scalequant=3.f;
  24. char *vqext_booktype="RESdata";
  25. quant_meta q={0,0,0,0}; /* set sequence data */
  26. int vqext_aux=0;
  27. static float *quant_save=NULL;
  28. float *vqext_weight(vqgen *v,float *p){
  29. return p;
  30. }
  31. /* quantize aligned on unit boundaries. Because our grid is likely
  32. very coarse, play 'shuffle the blocks'; don't allow multiple
  33. entries to fill the same spot as is nearly certain to happen. */
  34. void vqext_quantize(vqgen *v,quant_meta *q){
  35. int j,k;
  36. long dim=v->elements;
  37. long n=v->entries;
  38. float max=-1;
  39. float *test=alloca(sizeof(float)*dim);
  40. int moved=0;
  41. /* allow movement only to unoccupied coordinates on the coarse grid */
  42. for(j=0;j<n;j++){
  43. for(k=0;k<dim;k++){
  44. float val=_now(v,j)[k];
  45. float norm=rint(fabs(val)/scalequant);
  46. if(norm>max)max=norm;
  47. test[k]=norm;
  48. }
  49. /* allow move only if unoccupied */
  50. if(quant_save){
  51. for(k=0;k<n;k++)
  52. if(j!=k && memcmp(test,quant_save+dim*k,dim*sizeof(float))==0)
  53. break;
  54. if(k==n){
  55. if(memcmp(test,quant_save+dim*j,dim*sizeof(float)))
  56. moved++;
  57. memcpy(quant_save+dim*j,test,sizeof(float)*dim);
  58. }
  59. }else{
  60. memcpy(_now(v,j),test,sizeof(float)*dim);
  61. }
  62. }
  63. /* unlike the other trainers, we fill in our quantization
  64. information (as we know granularity beforehand and don't need to
  65. maximize it) */
  66. q->min=_float32_pack(0.f);
  67. q->delta=_float32_pack(scalequant);
  68. q->quant=_ilog(max);
  69. if(quant_save){
  70. memcpy(_now(v,0),quant_save,sizeof(float)*dim*n);
  71. fprintf(stderr,"cells shifted this iteration: %d\n",moved);
  72. }
  73. }
  74. /* candidate,actual */
  75. float vqext_metric(vqgen *v,float *e, float *p){
  76. int i;
  77. float acc=0.f;
  78. for(i=0;i<v->elements;i++){
  79. float val=p[i]-e[i];
  80. acc+=val*val;
  81. }
  82. return sqrt(acc);
  83. }
  84. /* We don't interleave here; we assume that the interleave is provided
  85. for us by residuesplit in vorbis/huff/ */
  86. void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){
  87. vqgen_addpoint(v,b+start,NULL);
  88. }
  89. /* need to reseed because of the coarse quantization we tend to use on
  90. residuals (which causes lots & lots of dupes) */
  91. void vqext_preprocess(vqgen *v){
  92. long i,j,k,l;
  93. float *test=alloca(sizeof(float)*v->elements);
  94. scalequant=q.quant;
  95. vqext_quantize(v,&q);
  96. vqgen_unquantize(v,&q);
  97. /* if there are any dupes, reseed */
  98. for(k=0;k<v->entries;k++){
  99. for(l=0;l<k;l++){
  100. if(memcmp(_now(v,k),_now(v,l),sizeof(float)*v->elements)==0)
  101. break;
  102. }
  103. if(l<k)break;
  104. }
  105. if(k<v->entries){
  106. fprintf(stderr,"reseeding with quantization....\n");
  107. /* seed the inputs to input points, but points on unit boundaries,
  108. ignoring quantbits for now, making sure each seed is unique */
  109. for(i=0,j=0;i<v->points && j<v->entries;i++){
  110. for(k=0;k<v->elements;k++){
  111. float val=_point(v,i)[k];
  112. test[k]=rint(val/scalequant)*scalequant;
  113. }
  114. for(l=0;l<j;l++){
  115. for(k=0;k<v->elements;k++)
  116. if(test[k]!=_now(v,l)[k])
  117. break;
  118. if(k==v->elements)break;
  119. }
  120. if(l==j){
  121. memcpy(_now(v,j),test,v->elements*sizeof(float));
  122. j++;
  123. }
  124. }
  125. if(j<v->elements){
  126. fprintf(stderr,"Not enough unique entries after prequantization\n");
  127. exit(1);
  128. }
  129. }
  130. vqext_quantize(v,&q);
  131. quant_save=_ogg_malloc(sizeof(float)*v->elements*v->entries);
  132. memcpy(quant_save,_now(v,0),sizeof(float)*v->elements*v->entries);
  133. vqgen_unquantize(v,&q);
  134. }