[xiph-commits] r13222 - trunk/ghost/libghost

jm at svn.xiph.org jm at svn.xiph.org
Wed Jul 4 11:10:49 PDT 2007


Author: jm
Date: 2007-07-04 11:10:49 -0700 (Wed, 04 Jul 2007)
New Revision: 13222

Modified:
   trunk/ghost/libghost/vorbis_psy.c
Log:
Reverse engineered some comments for bark_noise_hybridmp(). Hopefully, others
will complete this (I'm looking at you Monty!).


Modified: trunk/ghost/libghost/vorbis_psy.c
===================================================================
--- trunk/ghost/libghost/vorbis_psy.c	2007-07-04 17:58:43 UTC (rev 13221)
+++ trunk/ghost/libghost/vorbis_psy.c	2007-07-04 18:10:49 UTC (rev 13222)
@@ -99,27 +99,45 @@
   fclose(of);
 }
 
+/* These comments are an attempt to reverse-engineer Monty's 
+   code for this really cryptic function. Some comments may
+   not be accurate because I (JMV) didn't write this code.
+   
+   n: Number of frequency points
+   b: Bark scale definition (packed 16-bit values)
+   f: Power spectral density
+   noise: Returns noise masking curve
+   offset: magic (haven't figured it out yet)
+   fixed: no clue
+*/
 static void bark_noise_hybridmp(int n,const long *b,
                                 const float *f,
                                 float *noise,
                                 const float offset,
                                 const int fixed){
   
+  /* These are cumulative statistics from DC (0) to frequency i. This makes it
+     possible to find the statistics in any range by just subtracting two values*/
   float *N=alloca(n*sizeof(*N));
   float *X=alloca(n*sizeof(*N));
   float *XX=alloca(n*sizeof(*N));
   float *Y=alloca(n*sizeof(*N));
   float *XY=alloca(n*sizeof(*N));
 
+  /* These are accumulators for the statistics about the spectrum. For example,
+     tXX is \sum_i{x^2_i} */
   float tN, tX, tXX, tY, tXY;
   int i;
 
   int lo, hi;
   float R, A, B, D;
+  /* w is the weight, x is the frequency, y is the spectrum */
   float w, x, y;
 
+  /* Initialise statistics to zero */
   tN = tX = tXX = tY = tXY = 0.f;
 
+  /* Handling the DC separately (not sure why) */
   y = f[0] + offset;
   if (y < 1.f) y = 1.f;
 
@@ -135,11 +153,13 @@
   Y[0] = tY;
   XY[0] = tXY;
 
+  /* Loop over all (linear) frequencies */
   for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
     
     y = f[i] + offset;
     if (y < 1.f) y = 1.f;
 
+    /* The statistics are weighted based on the square of the spectrum (no clue why) */
     w = y * y;
     
     tN += w;
@@ -155,12 +175,15 @@
     XY[i] = tXY;
   }
   
+  /* Loop over the first critical band (but x and i are in linear scale) */
   for (i = 0, x = 0.f;; i++, x += 1.f) {
     
     lo = b[i] >> 16;
     if( lo>=0 ) break;
     hi = b[i] & 0xffff;
     
+    /* Not sure why the statistics are computed using -lo, probably some
+       kind of "mirroring" effect around the DC. */
     tN = N[hi] + N[-lo];
     tX = X[hi] - X[-lo];
     tXX = XX[hi] + XX[-lo];
@@ -177,26 +200,32 @@
     noise[i] = R - offset;
   }
   
+  /* Loop over the other critical bands (but x and i are in linear scale) */
   for ( ;; i++, x += 1.f) {
     
     lo = b[i] >> 16;
     hi = b[i] & 0xffff;
     if(hi>=n)break;
     
+    /* Compute all the statistics over the [lo,hi] interval only */
     tN = N[hi] - N[lo];
     tX = X[hi] - X[lo];
     tXX = XX[hi] - XX[lo];
     tY = Y[hi] - Y[lo];
     tXY = XY[hi] - XY[lo];
     
+    /* These appear to be linear regression coefficients of some kind */
     A = tY * tXX - tX * tXY;
     B = tN * tXY - tX * tY;
+    /* Variance of the spectrum over the current band */
     D = tN * tXX - tX * tX;
     R = (A + x * B) / D;
     if (R < 0.f) R = 0.f;
     
     noise[i] = R - offset;
   }
+  
+  /* Fill the rest with what was found for the last critical band */
   for ( ; i < n; i++, x += 1.f) {
     
     R = (A + x * B) / D;
@@ -205,8 +234,10 @@
     noise[i] = R - offset;
   }
   
+  /* Some magic stopping condition */
   if (fixed <= 0) return;
   
+  /* Loop over the first critical band (but x and i are in linear scale) */
   for (i = 0, x = 0.f;; i++, x += 1.f) {
     hi = i + fixed / 2;
     lo = hi - fixed;
@@ -226,6 +257,7 @@
 
     if (R - offset < noise[i]) noise[i] = R - offset;
   }
+  /* Loop over the other critical bands (but x and i are in linear scale) */
   for ( ;; i++, x += 1.f) {
     
     hi = i + fixed / 2;
@@ -245,6 +277,7 @@
     
     if (R - offset < noise[i]) noise[i] = R - offset;
   }
+  /* Fill the rest with what was found for the last critical band */
   for ( ; i < n; i++, x += 1.f) {
     R = (A + x * B) / D;
     if (R - offset < noise[i]) noise[i] = R - offset;



More information about the commits mailing list