[Datatype-cvs] aac/codec/fixpt/decoder/real dequant.c, 1.1, 1.2 sbr.c, 1.1, 1.2 sbr.h, 1.1, 1.2 sbrfreq.c, 1.1, 1.2 sbrhfadj.c, 1.1, 1.2 stproc.c, 1.1, 1.2
jrecker at helixcommunity.org jrecker at helixcommunity.orgUpdate of /cvsroot/datatype/aac/codec/fixpt/decoder/real
In directory cvs-new:/tmp/cvs-serv10133
Modified Files:
dequant.c sbr.c sbr.h sbrfreq.c sbrhfadj.c stproc.c
Log Message:
Updated SBR decoder to match corrections in spec
- affects logic for patch generation, limiter bands, sinusoids
Index: stproc.c
===================================================================
RCS file: /cvsroot/datatype/aac/codec/fixpt/decoder/real/stproc.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- stproc.c 26 Feb 2005 01:47:35 -0000 1.1
+++ stproc.c 20 May 2005 18:05:41 -0000 1.2
@@ -76,7 +76,7 @@
*
* Return: none
*
- * Notes: assume 1 guard bit in input
+ * Notes: assume no guard bits in input
* gains 0 int bits
**************************************************************************************/
static void StereoProcessGroup(int *coefL, int *coefR, const short *sfbTab,
@@ -125,16 +125,24 @@
} while (--width);
}
} else if ( cbIdx != 13 && ((msMaskPres == 1 && (msMask & 0x01)) || msMaskPres == 2) ) {
- /* mid-side stereo (assumes 1 GB in inputs) */
+ /* mid-side stereo (assumes no GB in inputs) */
do {
cl = *coefL;
cr = *coefR;
- sf = cl + cr;
+ if ( (FASTABS(cl) | FASTABS(cr)) >> 30 ) {
+ /* avoid overflow (rare) */
+ cl >>= 1;
+ sf = cl + (cr >> 1); CLIP_2N(sf, 30); sf <<= 1;
+ cl = cl - (cr >> 1); CLIP_2N(cl, 30); cl <<= 1;
+ } else {
+ /* usual case */
+ sf = cl + cr;
+ cl -= cr;
+ }
+
*coefL++ = sf;
gbMaskL |= FASTABS(sf);
-
- cl -= cr;
*coefR++ = cl;
gbMaskR |= FASTABS(cl);
} while (--width);
Index: sbr.c
===================================================================
RCS file: /cvsroot/datatype/aac/codec/fixpt/decoder/real/sbr.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sbr.c 26 Feb 2005 01:47:35 -0000 1.1
+++ sbr.c 20 May 2005 18:05:41 -0000 1.2
@@ -269,6 +269,11 @@
return ERR_AAC_NONE;
}
+ if (upsampleOnly) {
+ sbrFreq->kStart = 32;
+ sbrFreq->numQMFBands = 0;
+ }
+
for (ch = 0; ch < chBlock; ch++) {
sbrGrid = &(psi->sbrGrid[chBase + ch]);
sbrChan = &(psi->sbrChan[chBase + ch]);
@@ -287,7 +292,7 @@
}
/* step 1 - analysis QMF */
- qmfaBands = (sbrHdr->count > 0 ? sbrFreq->kStart : 32);
+ qmfaBands = sbrFreq->kStart;
for (l = 0; l < 32; l++) {
gbMask = QMFAnalysis(inbuf + l*32, psi->delayQMFA[chBase + ch], psi->XBuf[l + HF_GEN][0],
aacDecInfo->rawSampleFBits, &(psi->delayIdxQMFA[chBase + ch]), qmfaBands);
@@ -305,8 +310,28 @@
outptr += 64*aacDecInfo->nChans;
}
} else {
+ /* if previous frame had lower SBR starting freq than current, zero out the synthesized QMF
+ * bands so they aren't used as sources for patching
+ * after patch generation, restore from delay buffer
+ * can only happen after header reset
+ */
+ for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) {
+ for (l = 0; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) {
+ psi->XBuf[l][k][0] = 0;
+ psi->XBuf[l][k][1] = 0;
+ }
+ }
+
/* step 2 - HF generation */
GenerateHighFreq(psi, sbrGrid, sbrFreq, sbrChan, ch);
+
+ /* restore SBR bands that were cleared before patch generation (time slots 0, 1 no longer needed) */
+ for (k = sbrFreq->kStartPrev; k < sbrFreq->kStart; k++) {
+ for (l = HF_ADJ; l < sbrGrid->envTimeBorder[0] + HF_ADJ; l++) {
+ psi->XBuf[l][k][0] = psi->XBufDelay[chBase + ch][l][k][0];
+ psi->XBuf[l][k][1] = psi->XBufDelay[chBase + ch][l][k][1];
+ }
+ }
/* step 3 - HF adjustment */
AdjustHighFreq(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch);
Index: sbrfreq.c
===================================================================
RCS file: /cvsroot/datatype/aac/codec/fixpt/decoder/real/sbrfreq.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sbrfreq.c 26 Feb 2005 01:47:35 -0000 1.1
+++ sbrfreq.c 20 May 2005 18:05:41 -0000 1.2
@@ -444,6 +444,10 @@
patchNumSubbands[numPatches] = MAX(sb - usb, 0);
patchStartSubband[numPatches] = k0 - oddFlag - patchNumSubbands[numPatches];
+ /* from MPEG reference code - slightly different from spec */
+ if ((patchNumSubbands[numPatches] < 3) && (numPatches > 0))
+ break;
+
if (patchNumSubbands[numPatches] > 0) {
usb = sb;
msb = sb;
@@ -452,14 +456,10 @@
msb = kStart;
}
- if (sb == freqMaster[k])
+ if (freqMaster[k] - sb < 3)
k = nMaster;
- ASSERT(numPatches <= 5);
- } while (sb != kStart + numQMFBands);
-
- if (patchNumSubbands[numPatches-1] < 3 && numPatches > 1)
- numPatches--;
+ } while (sb != (kStart + numQMFBands) && numPatches <= MAX_NUM_PATCHES);
return numPatches;
}
@@ -546,8 +546,10 @@
bands = limBandsPerOctave[limiterBands - 1];
patchBorders[0] = kStart;
- for (k = 1; k <= numPatches; k++)
+ /* from MPEG reference code - slightly different from spec (top border) */
+ for (k = 1; k < numPatches; k++)
patchBorders[k] = patchBorders[k-1] + patchNumSubbands[k-1];
+ patchBorders[k] = freqLow[nLow];
for (k = 0; k <= nLow; k++)
freqLimiter[k] = freqLow[k];
Index: dequant.c
===================================================================
RCS file: /cvsroot/datatype/aac/codec/fixpt/decoder/real/dequant.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dequant.c 26 Feb 2005 01:47:34 -0000 1.1
+++ dequant.c 20 May 2005 18:05:41 -0000 1.2
@@ -137,7 +137,7 @@
* Notes: applies dequant formula y = pow(x, 4.0/3.0) * pow(2, (scale - 100)/4.0)
* * pow(2, FBITS_OUT_DQ_OFF)
* clips outputs to Q(FBITS_OUT_DQ_OFF)
- * output has >= 1 guard bit
+ * output has no minimum number of guard bits
**************************************************************************************/
static int DequantBlock(int *inbuf, int nSamps, int scale)
{
@@ -172,8 +172,8 @@
shift = 31;
for (x = 0; x < 4; x++) {
y = tab16[x];
- if (y > (0x3fffffff >> shift))
- y = 0x3fffffff; /* clip (rare), guarantees at least 1 gb */
+ if (y > (0x7fffffff >> shift))
+ y = 0x7fffffff; /* clip (rare) */
else
y <<= shift;
tab4[x] = y;
@@ -247,8 +247,8 @@
if (shift > 31)
shift = 31;
- if (y > (0x3fffffff >> shift))
- y = 0x3fffffff; /* clip (rare), guarantees at least 1 gb */
+ if (y > (0x7fffffff >> shift))
+ y = 0x7fffffff; /* clip (rare) */
else
y <<= shift;
} else {
Index: sbr.h
===================================================================
RCS file: /cvsroot/datatype/aac/codec/fixpt/decoder/real/sbr.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sbr.h 26 Feb 2005 01:47:35 -0000 1.1
+++ sbr.h 20 May 2005 18:05:41 -0000 1.2
@@ -241,9 +241,8 @@
unsigned char freqLimiter[MAX_QMF_BANDS / 2 + MAX_NUM_PATCHES]; /* max (intermediate) size = nLow + numPatches - 1 */
unsigned char numPatches;
- unsigned char patchBorders[MAX_NUM_PATCHES+1];
- unsigned char patchNumSubbands[MAX_NUM_PATCHES];
- unsigned char patchStartSubband[MAX_NUM_PATCHES];
+ unsigned char patchNumSubbands[MAX_NUM_PATCHES + 1];
+ unsigned char patchStartSubband[MAX_NUM_PATCHES + 1];
} SBRFreq;
typedef struct _SBRChan {
@@ -257,7 +256,7 @@
unsigned char invfMode[2][MAX_NUM_NOISE_FLOOR_BANDS]; /* invfMode[0/1][band] = prev/curr */
int chirpFact[MAX_NUM_NOISE_FLOOR_BANDS]; /* bwArray */
unsigned char addHarmonicFlag[2]; /* addHarmonicFlag[0/1] = prev/curr */
- unsigned char addHarmonic[2][MAX_QMF_BANDS]; /* addHarmonic[0/1][band] = prev/curr */
+ unsigned char addHarmonic[2][64]; /* addHarmonic[0/1][band] = prev/curr */
int gbMask[2]; /* gbMask[0/1] = XBuf[0-31]/XBuf[32-39] */
signed char laPrev;
Index: sbrhfadj.c
===================================================================
RCS file: /cvsroot/datatype/aac/codec/fixpt/decoder/real/sbrhfadj.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sbrhfadj.c 26 Feb 2005 01:47:35 -0000 1.1
+++ sbrhfadj.c 20 May 2005 18:05:41 -0000 1.2
@@ -189,21 +189,25 @@
**************************************************************************************/
static int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int band, int la)
{
- int bandStart, bandEnd, oddFlag;
+ int bandStart, bandEnd, oddFlag, r;
if (sbrGrid->freqRes[env]) {
/* high resolution */
- if (env >= la || (sbrChan->addHarmonicFlag[0] && sbrChan->addHarmonic[0][band]))
- return sbrChan->addHarmonic[1][band];
+ bandStart = band;
+ bandEnd = band+1;
} else {
/* low resolution (see CalcFreqLow() for mapping) */
oddFlag = sbrFreq->nHigh & 0x01;
- bandStart = 2*band - oddFlag; /* starting index for freqLow[band] */
- bandEnd = 2*(band+1) - oddFlag; /* ending index for freqLow[band+1] */
- for (band = bandStart; band < bandEnd; band++) {
- if (env >= la || (sbrChan->addHarmonicFlag[0] && sbrChan->addHarmonic[0][band]))
- if (sbrChan->addHarmonic[1][band])
- return 1;
+ bandStart = (band > 0 ? 2*band - oddFlag : 0); /* starting index for freqLow[band] */
+ bandEnd = 2*(band+1) - oddFlag; /* ending index for freqLow[band+1] */
+ }
+
+ /* sMapped = 1 if sIndexMapped == 1 for any frequency in this band */
+ for (band = bandStart; band < bandEnd; band++) {
+ if (sbrChan->addHarmonic[1][band]) {
+ r = ((sbrFreq->freqHigh[band+1] + sbrFreq->freqHigh[band]) >> 1);
+ if (env >= la || sbrChan->addHarmonic[0][r] == 1)
+ return 1;
}
}
return 0;
@@ -380,13 +384,28 @@
psi->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, psi->sBand, psi->la);
}
+ /* get sIndexMapped for this QMF subband */
sIndexMapped = 0;
- if (env >= psi->la || (sbrChan->addHarmonicFlag[0] && sbrChan->addHarmonic[0][psi->highBand])) {
- r = ((sbrFreq->freqHigh[psi->highBand+1] + sbrFreq->freqHigh[psi->highBand]) >> 1); /* r = center band */
- if (m == r - sbrFreq->kStart)
+ r = ((sbrFreq->freqHigh[psi->highBand+1] + sbrFreq->freqHigh[psi->highBand]) >> 1);
+ if (m + sbrFreq->kStart == r) {
+ /* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */
+ if (env >= psi->la || sbrChan->addHarmonic[0][r] == 1)
sIndexMapped = sbrChan->addHarmonic[1][psi->highBand];
}
+ /* save sine flags from last envelope in this frame:
+ * addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband
+ * addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band
+ * from MPEG reference code - slightly different from spec
+ * (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la)
+ */
+ if (env == sbrGrid->numEnv - 1) {
+ if (m + sbrFreq->kStart == r)
+ sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][psi->highBand];
+ else
+ sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0;
+ }
+
gain = psi->envDataDequant[ch][env][psi->sBand];
qm = MULSHIFT32(gain, psi->qqp1Inv) << 1;
sm = (sIndexMapped ? MULSHIFT32(gain, psi->qp1Inv) << 1 : 0);
@@ -819,9 +838,11 @@
hfReset = 0; /* only set for first envelope after header reset */
}
- /* save curr as prev for next time */
- for (i = 0; i < MAX_QMF_BANDS; i++)
- sbrChan->addHarmonic[0][i] = sbrChan->addHarmonic[1][i];
+ /* set saved sine flags to 0 for QMF bands outside of current frequency range */
+ for (i = 0; i < sbrFreq->freqLimiter[0] + sbrFreq->kStart; i++)
+ sbrChan->addHarmonic[0][i] = 0;
+ for (i = sbrFreq->freqLimiter[sbrFreq->nLimiter] + sbrFreq->kStart; i < 64; i++)
+ sbrChan->addHarmonic[0][i] = 0;
sbrChan->addHarmonicFlag[0] = sbrChan->addHarmonicFlag[1];
/* save la for next frame */