lspdata.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
  6. * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE OggVorbis 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: metrics and quantization code for LSP VQ codebooks
  14. last mod: $Id: lspdata.c,v 1.13.2.3 2000/11/04 06:43:55 xiphmont Exp $
  15. ********************************************************************/
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <stdio.h>
  19. #include "vqgen.h"
  20. #include "vqext.h"
  21. #include "../lib/sharedbook.h"
  22. char *vqext_booktype="LSPdata";
  23. quant_meta q={0,0,0,1}; /* set sequence data */
  24. int vqext_aux=1;
  25. float global_maxdel=M_PI;
  26. float global_mindel=M_PI;
  27. #if 0
  28. void vqext_quantize(vqgen *v,quant_meta *q){
  29. float delta,mindel;
  30. float maxquant=((1<<q->quant)-1);
  31. int j,k;
  32. /* first find the basic delta amount from the maximum span to be
  33. encoded. Loosen the delta slightly to allow for additional error
  34. during sequence quantization */
  35. delta=(global_maxdel-global_mindel)/((1<<q->quant)-1.5);
  36. q->min=_float32_pack(global_mindel);
  37. q->delta=_float32_pack(delta);
  38. mindel=_float32_unpack(q->min);
  39. delta=_float32_unpack(q->delta);
  40. for(j=0;j<v->entries;j++){
  41. float last=0;
  42. for(k=0;k<v->elements;k++){
  43. float val=_now(v,j)[k];
  44. float now=rint((val-last-mindel)/delta);
  45. _now(v,j)[k]=now;
  46. if(now<0){
  47. /* be paranoid; this should be impossible */
  48. fprintf(stderr,"fault; quantized value<0\n");
  49. exit(1);
  50. }
  51. if(now>maxquant){
  52. /* be paranoid; this should be impossible */
  53. fprintf(stderr,"fault; quantized value>max\n");
  54. exit(1);
  55. }
  56. last=(now*delta)+mindel+last;
  57. }
  58. }
  59. }
  60. #else
  61. void vqext_quantize(vqgen *v,quant_meta *q){
  62. vqgen_quantize(v,q);
  63. }
  64. #endif
  65. float *weight=NULL;
  66. #if 0
  67. /* LSP training metric. We weight error proportional to distance
  68. *between* LSP vector values. The idea of this metric is not to set
  69. final cells, but get the midpoint spacing into a form conducive to
  70. what we want, which is weighting toward preserving narrower
  71. features. */
  72. #define FUDGE (global_maxdel-weight[i])
  73. float *vqext_weight(vqgen *v,float *p){
  74. int i;
  75. int el=v->elements;
  76. float lastp=0.;
  77. for(i=0;i<el;i++){
  78. float predist=(p[i]-lastp);
  79. float postdist=(p[i+1]-p[i]);
  80. weight[i]=(predist<postdist?predist:postdist);
  81. lastp=p[i];
  82. }
  83. return p;
  84. }
  85. #else
  86. #define FUDGE 1.
  87. float *vqext_weight(vqgen *v,float *p){
  88. return p;
  89. }
  90. #endif
  91. /* candidate,actual */
  92. float vqext_metric(vqgen *v,float *e, float *p){
  93. int i;
  94. int el=v->elements;
  95. float acc=0.;
  96. for(i=0;i<el;i++){
  97. float val=(p[i]-e[i])*FUDGE;
  98. acc+=val*val;
  99. }
  100. return sqrt(acc/v->elements);
  101. }
  102. /* Data files are line-vectors, now just deltas. The codebook entries
  103. want to be monotonically increasing, so we adjust */
  104. /* assume vqext_aux==1 */
  105. void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){
  106. float *a=alloca(sizeof(float)*(dim+1)); /* +aux */
  107. float base=0;
  108. int i;
  109. for(i=0;i<dim;i++)
  110. base=a[i]=b[i+start]+base;
  111. if(start+dim+1>cols) /* +aux */
  112. a[i]=M_PI;
  113. else
  114. a[i]=b[i+start]+base;
  115. vqgen_addpoint(v,a,a+dim);
  116. }
  117. /* we just need to calc the global_maxdel from the training set */
  118. void vqext_preprocess(vqgen *v){
  119. long j,k;
  120. global_maxdel=0.;
  121. global_mindel=M_PI;
  122. for(j=0;j<v->points;j++){
  123. float last=0.;
  124. for(k=0;k<v->elements+v->aux;k++){
  125. float p=_point(v,j)[k];
  126. if(p-last>global_maxdel)global_maxdel=p-last;
  127. if(p-last<global_mindel)global_mindel=p-last;
  128. last=p;
  129. }
  130. }
  131. weight=_ogg_malloc(sizeof(float)*v->elements);
  132. }