shithub: aacenc

Download patch

ref: 3ec0a8fc640e88557689a72fcd99f2e5ed2691f3
parent: 1b57f513d472f28cff94b5d390b1220eeb1f359c
author: knik <knik>
date: Sun Sep 7 12:45:48 EDT 2003

Better block switch. Removed long fft code.

--- a/libfaac/psych.h
+++ b/libfaac/psych.h
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: psych.h,v 1.11 2003/06/26 19:20:42 knik Exp $
+ * $Id: psych.h,v 1.12 2003/09/07 16:45:48 knik Exp $
  */
 
 #ifndef PSYCH_H
@@ -67,8 +67,9 @@
 			PsyInfo *psyInfo, int *cb_width_long, int num_cb_long,
 			int *cb_width_short, int num_cb_short,
 			unsigned int numChannels);
-  void (*PsyBufferUpdate) (GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo,
-			   double *newSamples, unsigned int bandwidth);
+  void (*PsyBufferUpdate) (GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo,
+			    double *newSamples, unsigned int bandwidth,
+			    int *cb_width_short, int num_cb_short);
   void (*BlockSwitch) (CoderInfo *coderInfo, PsyInfo *psyInfo,
 		       unsigned int numChannels);
 } psymodel_t;
--- a/libfaac/psychkni.c
+++ b/libfaac/psychkni.c
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: psychkni.c,v 1.12 2003/08/18 16:22:10 knik Exp $
+ * $Id: psychkni.c,v 1.13 2003/09/07 16:45:48 knik Exp $
  */
 #include <stdio.h>
 #include <stdlib.h>
@@ -28,27 +28,19 @@
 #include "util.h"
 #include "frame.h"
 
-#define PREPARELONGFFT 0
+typedef float psyfloat;
 
-typedef double psyfloat;
-
 typedef struct
 {
-  // bandwidth
-  int band;
+  /* bandwidth */
   int bandS;
+  int lastband;
 
-  /* FFT data */
-
-  /* energy */
-#if PREPARELONGFFT
-  psyfloat *fftEnrg;
-  psyfloat *fftEnrgNext;
-  psyfloat *fftEnrgNext2;
-#endif
+  /* SFB energy */
   psyfloat *fftEnrgS[8];
   psyfloat *fftEnrgNextS[8];
   psyfloat *fftEnrgNext2S[8];
+  psyfloat *fftEnrgPrevS[8];
 }
 psydata_t;
 
@@ -70,68 +62,91 @@
   }
 }
 
-static void PsyThreshold(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, int *cb_width_long,
-			 int num_cb_long, int *cb_width_short, int num_cb_short)
+static void PsyCheckShort(PsyInfo * psyInfo)
 {
   double totvol = 0.0;
   double totchg, totchg2;
-  int lastband;
   psydata_t *psydata = psyInfo->data;
+  int lastband = psydata->lastband;
   int firstband = 1;
-  int first = 0;
-  int last = 0;
   int sfb;
 
   /* long/short block switch */
   totchg = totchg2 = 0.0;
-  for (sfb = 0; sfb < num_cb_short; sfb++)
+  for (sfb = 0; sfb < lastband; sfb++)
   {
     int win;
-    double volb[8+1]; // 1 window comes from next frame
+    double volb[16];
+    double vavg[13];
     double maxdif = 0.0;
     double totmaxdif = 0.0;
-    double e;
-    int l;
+    double e, v;
 
-    first = last;
-    last = first + cb_width_short[sfb];
+    // previous frame
+    for (win = 0; win < 4; win++)
+    {
+      e = psydata->fftEnrgPrevS[win + 4][sfb];
 
-    if (first < 1)
-      first = 1;
+      volb[win] = sqrt(e);
+      totvol += e;
+    }
 
-      if (last > psydata->bandS) // band out of range
-      break;
-
-    // 8 windows of current frame
+    // current frame
     for (win = 0; win < 8; win++)
       {
-      e = 0.0;
-      for (l = first; l < last; l++)
-	e += psydata->fftEnrgS[win][l];
+      e = psydata->fftEnrgS[win][sfb];
 
-      volb[win] = sqrt(e);
+      volb[win + 4] = sqrt(e);
       totvol += e;
     }
-    // 1 window of next frame
-    e = 0.0;
-    for (l = first; l < last; l++)
-      e += psydata->fftEnrgNextS[0][l];
+    // next frame
+    for (win = 0; win < 4; win++)
+    {
+      e = psydata->fftEnrgNextS[win][sfb];
 
-    volb[8] = sqrt(e);
+      volb[win + 12] = sqrt(e);
     totvol += e;
+    }
 
-    // don't calculate energy change in lowest bands
+    // ignore lowest SFBs
     if (sfb < firstband)
       continue;
 
-    if ((volb[0] > 0.0) || (volb[8] > 0.0))
+    v = 0.0;
+    for (win = 0; win < 4; win++)
     {
-      for (win = 1; win < 8; win++)
+      v += volb[win];
+    }
+    vavg[0] = 0.25 * v;
+
+    for (win = 1; win < 13; win++)
       {
-	double slowvol = (1.0 / 8.0) * ((8 - win) * volb[0] + win * volb[8]);
-	double voldif = fabs((volb[win] - slowvol) / slowvol);
-	double totvoldif = (volb[win] - slowvol) * (volb[win] - slowvol);
+      v -= volb[win - 1];
+      v += volb[win + 3];
+      vavg[win] = 0.25 * v;
+    }
 
+    for (win = 0; win < 8; win++)
+    {
+      int i;
+      double mina, maxv;
+      double voldif;
+      double totvoldif;
+
+      mina = vavg[win];
+      for (i = 1; i < 5; i++)
+        mina = min(mina, vavg[win + i]);
+
+      maxv = volb[win + 2];
+      for (i = 3; i < 6; i++)
+        maxv = max(maxv, volb[win + i]);
+
+      if (!maxv || !mina)
+        continue;
+
+      voldif = (maxv - mina) / mina;
+      totvoldif = (maxv - mina) * (maxv - mina);
+
 	if (voldif > maxdif)
 	  maxdif = voldif;
 
@@ -138,12 +153,9 @@
 	if (totvoldif > totmaxdif)
 	  totmaxdif = totvoldif;
       }
-    }
     totchg += maxdif;
     totchg2 += totmaxdif;
   }
-  //lastband = num_cb_short;
-  lastband = sfb;
 
   totvol = sqrt(totvol);
 
@@ -155,8 +167,9 @@
   else
     totchg2 = 0.0;
 
-  psyInfo->block_type = ((totchg > 0.75) && (totchg2 > 0.10))
+  psyInfo->block_type = ((totchg > 1.0) && (totchg2 > 0.07))
     ? ONLY_SHORT_WINDOW : ONLY_LONG_WINDOW;
+  //psyInfo->block_type = 0 ? ONLY_SHORT_WINDOW : ONLY_LONG_WINDOW;
 
 #if 0
   {
@@ -205,24 +218,11 @@
   size = BLOCK_LEN_LONG;
   for (channel = 0; channel < numChannels; channel++)
   {
-#if PREPARELONGFFT
-    psydata_t *psydata = psyInfo[channel].data;
-#endif
-
     psyInfo[channel].size = size;
 
     psyInfo[channel].prevSamples =
       (double *) AllocMemory(size * sizeof(double));
     memset(psyInfo[channel].prevSamples, 0, size * sizeof(double));
-
-#if PREPARELONGFFT
-    psydata->fftEnrg = (psyfloat *) AllocMemory(size * sizeof(psyfloat));
-    memset(psydata->fftEnrg, 0, size * sizeof(psyfloat));
-    psydata->fftEnrgNext = (psyfloat *) AllocMemory(size * sizeof(psyfloat));
-    memset(psydata->fftEnrgNext, 0, size * sizeof(psyfloat));
-    psydata->fftEnrgNext2 = (psyfloat *) AllocMemory(size * sizeof(psyfloat));
-    memset(psydata->fftEnrgNext2, 0, size * sizeof(psyfloat));
-#endif
   }
 
   size = BLOCK_LEN_SHORT;
@@ -238,15 +238,18 @@
 
     for (j = 0; j < 8; j++)
     {
+      psydata->fftEnrgPrevS[j] =
+	(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
+      memset(psydata->fftEnrgPrevS[j], 0, NSFB_SHORT * sizeof(psyfloat));
       psydata->fftEnrgS[j] =
-	(psyfloat *) AllocMemory(size * sizeof(psyfloat));
-      memset(psydata->fftEnrgS[j], 0, size * sizeof(psyfloat));
+	(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
+      memset(psydata->fftEnrgS[j], 0, NSFB_SHORT * sizeof(psyfloat));
       psydata->fftEnrgNextS[j] =
-	(psyfloat *) AllocMemory(size * sizeof(psyfloat));
-      memset(psydata->fftEnrgNextS[j], 0, size * sizeof(psyfloat));
+	(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
+      memset(psydata->fftEnrgNextS[j], 0, NSFB_SHORT * sizeof(psyfloat));
       psydata->fftEnrgNext2S[j] =
-	(psyfloat *) AllocMemory(size * sizeof(psyfloat));
-      memset(psydata->fftEnrgNext2S[j], 0, size * sizeof(psyfloat));
+	(psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat));
+      memset(psydata->fftEnrgNext2S[j], 0, NSFB_SHORT * sizeof(psyfloat));
     }
   }
 }
@@ -263,21 +266,8 @@
 
   for (channel = 0; channel < numChannels; channel++)
   {
-#if PREPARELONGFFT
-    psydata_t *psydata = psyInfo[channel].data;
-#endif
-
     if (psyInfo[channel].prevSamples)
       FreeMemory(psyInfo[channel].prevSamples);
-
-#if PREPARELONGFFT
-    if (psydata->fftEnrg)
-      FreeMemory(psydata->fftEnrg);
-    if (psydata->fftEnrgNext)
-      FreeMemory(psydata->fftEnrgNext);
-    if (psydata->fftEnrgNext2)
-      FreeMemory(psydata->fftEnrgNext2);
-#endif
   }
 
   for (channel = 0; channel < numChannels; channel++)
@@ -288,6 +278,8 @@
       FreeMemory(psyInfo[channel].prevSamplesS);
     for (j = 0; j < 8; j++)
     {
+      if (psydata->fftEnrgPrevS[j])
+	FreeMemory(psydata->fftEnrgPrevS[j]);
       if (psydata->fftEnrgS[j])
 	FreeMemory(psydata->fftEnrgS[j]);
       if (psydata->fftEnrgNextS[j])
@@ -324,11 +316,8 @@
 	int leftChan = channel;
 	int rightChan = channelInfo[channel].paired_ch;
 
-	/* Calculate the threshold */
-	PsyThreshold(gpsyInfo, &psyInfo[leftChan], cb_width_long, num_cb_long,
-		     cb_width_short, num_cb_short);
-	PsyThreshold(gpsyInfo, &psyInfo[rightChan], cb_width_long, num_cb_long,
-		     cb_width_short, num_cb_short);
+	PsyCheckShort(&psyInfo[leftChan]);
+	PsyCheckShort(&psyInfo[rightChan]);
       }
       else if (!channelInfo[channel].cpe &&
 	       channelInfo[channel].lfe)
@@ -338,9 +327,7 @@
       }
       else if (!channelInfo[channel].cpe)
       {				/* SCE */
-	/* Calculate the threshold */
-	PsyThreshold(gpsyInfo, &psyInfo[channel], cb_width_long, num_cb_long,
-		     cb_width_short, num_cb_short);
+	PsyCheckShort(&psyInfo[channel]);
       }
     }
   }
@@ -347,52 +334,27 @@
 }
 
 static void PsyBufferUpdate(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo,
-			    double *newSamples, unsigned int bandwidth)
+			    double *newSamples, unsigned int bandwidth,
+			    int *cb_width_short, int num_cb_short)
 {
-  int i, j;
-  double a, b;
+  int win;
   double transBuff[2 * BLOCK_LEN_LONG];
   double transBuffS[2 * BLOCK_LEN_SHORT];
   psydata_t *psydata = psyInfo->data;
   psyfloat *tmp;
+  int sfb;
 
-  psydata->band = psyInfo->size * bandwidth * 2 / gpsyInfo->sampleRate;
   psydata->bandS = psyInfo->sizeS * bandwidth * 2 / gpsyInfo->sampleRate;
 
-#if PREPARELONGFFT
   memcpy(transBuff, psyInfo->prevSamples, psyInfo->size * sizeof(double));
   memcpy(transBuff + psyInfo->size, newSamples, psyInfo->size * sizeof(double));
 
-  Hann(gpsyInfo, transBuff, 2 * psyInfo->size);
-  rfft(transBuff, 11);
-
-  // shift bufs
-  tmp = psydata->fftEnrg;
-  psydata->fftEnrg = psydata->fftEnrgNext;
-  psydata->fftEnrgNext = psydata->fftEnrgNext2;
-  psydata->fftEnrgNext2 = tmp;
-
-  for (i = 0; i < psydata->band; i++)
+  for (win = 0; win < 8; win++)
   {
-    a = transBuff[i];
-    b = transBuff[i + psyInfo->size];
-    // spectral line energy
-    psydata->fftEnrgNext2[i] = a * a + b * b;
-    //printf("psyInfo->fftEnrg[%d]: %g\n", i, psyInfo->fftEnrg[i]);
-  }
-  for (; i < psyInfo->size; i++)
-  {
-    psydata->fftEnrgNext2[i] = 0;
-    //printf("psyInfo->fftEnrg[%d]: %g\n", i, psyInfo->fftEnrg[i]);
-  }
-#endif
+    int first = 0;
+    int last = 0;
 
-  memcpy(transBuff, psyInfo->prevSamples, psyInfo->size * sizeof(double));
-  memcpy(transBuff + psyInfo->size, newSamples, psyInfo->size * sizeof(double));
-
-  for (j = 0; j < 8; j++)
-  {
-    memcpy(transBuffS, transBuff + (j * 128) + (512 - 64),
+    memcpy(transBuffS, transBuff + (win * 128) + (512 - 64),
 	   2 * psyInfo->sizeS * sizeof(double));
 
     Hann(gpsyInfo, transBuffS, 2 * psyInfo->sizeS);
@@ -399,23 +361,42 @@
     rfft(transBuffS, 8);
 
     // shift bufs
-    tmp = psydata->fftEnrgS[j];
-    psydata->fftEnrgS[j] = psydata->fftEnrgNextS[j];
-    psydata->fftEnrgNextS[j] = psydata->fftEnrgNext2S[j];
-    psydata->fftEnrgNext2S[j] = tmp;
+    tmp = psydata->fftEnrgPrevS[win];
+    psydata->fftEnrgPrevS[win] = psydata->fftEnrgS[win];
+    psydata->fftEnrgS[win] = psydata->fftEnrgNextS[win];
+    psydata->fftEnrgNextS[win] = psydata->fftEnrgNext2S[win];
+    psydata->fftEnrgNext2S[win] = tmp;
 
-    for (i = 0; i < psydata->bandS; i++)
+    for (sfb = 0; sfb < num_cb_short; sfb++)
     {
-      a = transBuffS[i];
-      b = transBuffS[i + psyInfo->sizeS];
-      // spectral line energy
-      psydata->fftEnrgNext2S[j][i] = a * a + b * b;
-      //printf("psyInfo->fftEnrgS[%d][%d]: %g\n", j, i, psyInfo->fftEnrgS[j][i]);
+      double e;
+      int l;
+
+      first = last;
+      last = first + cb_width_short[sfb];
+
+      if (first < 1)
+	first = 1;
+
+      //if (last > psydata->bandS) // band out of range
+      if (first >= psydata->bandS) // band out of range
+	break;
+
+      e = 0.0;
+      for (l = first; l < last; l++)
+      {
+	double a = transBuffS[l];
+	double b = transBuffS[l + psyInfo->sizeS];
+
+	e += a * a + b * b;
+      }
+
+      psydata->fftEnrgNext2S[win][sfb] = e;
     }
-    for (; i < psyInfo->sizeS; i++)
+    psydata->lastband = sfb;
+    for (; sfb < num_cb_short; sfb++)
     {
-      psydata->fftEnrgNext2S[j][i] = 0;
-      //printf("psyInfo->fftEnrgS[%d][%d]: %g\n", j, i, psyInfo->fftEnrgS[j][i]);
+      psydata->fftEnrgNext2S[win][sfb] = 0;
     }
   }