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;
}
}