lspdata.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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: metrics and quantization code for LSP VQ codebooks
  14. last mod: $Id: lspdata.c,v 1.12.8.1 2000/08/31 09:00:03 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, starting with zero. If we want to
  103. train on a subvector starting in the middle, we need to adjust the
  104. data as if it was starting at zero. we also need to add the 'aux'
  105. value, which is an extra point at the end so we have leading and
  106. trailing space */
  107. /* assume vqext_aux==1 */
  108. void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){
  109. float *a=alloca(sizeof(float)*(dim+1)); /* +aux */
  110. float base=0;
  111. int i;
  112. if(start>0)base=b[start-1];
  113. for(i=0;i<dim;i++)a[i]=b[i+start]-base;
  114. if(start+dim+1>cols) /* +aux */
  115. a[i]=a[i-1];
  116. else
  117. a[i]=b[i+start]-base;
  118. vqgen_addpoint(v,a,a+dim);
  119. }
  120. /* we just need to calc the global_maxdel from the training set */
  121. void vqext_preprocess(vqgen *v){
  122. long j,k;
  123. global_maxdel=0.;
  124. global_mindel=M_PI;
  125. for(j=0;j<v->points;j++){
  126. float last=0.;
  127. for(k=0;k<v->elements+v->aux;k++){
  128. float p=_point(v,j)[k];
  129. if(p-last>global_maxdel)global_maxdel=p-last;
  130. if(p-last<global_mindel)global_mindel=p-last;
  131. last=p;
  132. }
  133. }
  134. weight=malloc(sizeof(float)*v->elements);
  135. }