diff --git a/src/lib/exhaleEnc.cpp b/src/lib/exhaleEnc.cpp index 0a6eaa8..6e449d0 100644 --- a/src/lib/exhaleEnc.cpp +++ b/src/lib/exhaleEnc.cpp @@ -420,7 +420,7 @@ unsigned ExhaleEncoder::applyTnsToWinGroup (TnsData& tnsData, SfbGroupData& grpD { const int numSwbWin = (eightShorts ? m_numSwbShort : m_numSwbLong); uint8_t tnsMaxBands = tnsScaleFactorBandLimit[eightShorts ? 1 : 0][m_swbTableIdx]; - uint8_t tnsStartSfb = 3 + 32000 / toSamplingRate (m_frequencyIdx); // 8-short TNS start + int tnsStartSfb = 3 + 32000 / toSamplingRate (m_frequencyIdx); // 8-short TNS start if (!eightShorts) { @@ -482,7 +482,7 @@ unsigned ExhaleEncoder::applyTnsToWinGroup (TnsData& tnsData, SfbGroupData& grpD // recalculate SFB RMS in TNS range errorValue |= m_specAnalyzer.getMeanAbsValues (mdctSignal, nullptr /*MDST wasn't filtered*/, grpSO[grpData.sfbsPerGroup], - 0 /*ci*/, &grpSO[tnsStartSfb], __max (0, tnsMaxBands - (int) tnsStartSfb), + 0 /*ci*/, &grpSO[tnsStartSfb], __max (0, tnsMaxBands - tnsStartSfb), &grpData.sfbRmsValues[tnsStartSfb + m_numSwbShort * tnsData.filteredWindow]); } else tnsData.filterOrder[0] = tnsData.numFilters = 0; // disable zero-length TNS filters @@ -1177,7 +1177,6 @@ unsigned ExhaleEncoder::spectralProcessing () // complete ics_info(), calc TNS unsigned errorValue = 0; // no error // get spectral channel statistics for last frame, used for input bandwidth (BW) detection -//m_specAnalyzer.getSpecAnalysisStats (m_specAnaPrev, nChannels); m_specAnalyzer.getSpectralBandwidth (m_bandwidPrev, nChannels); // spectral analysis for current MCLT signal (windowed time-samples for the current frame) @@ -1494,6 +1493,10 @@ unsigned ExhaleEncoder::temporalProcessing () // determine time-domain aspects o tsCurr[ch] = (m_tempAnaCurr[ci] /*R*/) & UCHAR_MAX; tsNext[ch] = (m_tempAnaNext[ci] >> 8) & UCHAR_MAX; + // save maximum spectral flatness of current and neighboring frames for quantization + // m_specFlatPrev[ci] = __max (m_specFlatPrev[ci], (m_specAnaCurr[ci] >> 16) & UCHAR_MAX); + m_tempAnaCurr [ci] = (m_tempAnaCurr[ci] & 0xFFFFFF) | (__max (sfCurr, __max (m_specFlatPrev[ci], sfNext)) << 24); + m_specFlatPrev[ci] = (uint8_t) sfCurr; const bool lowOlapNext = (m_tranLocNext[ci] >= 0) || (sfNext <= UCHAR_MAX / 4 && tfNext > (UCHAR_MAX * 13) / 16) || (tsCurr[ch] > (UCHAR_MAX * 5) / 8) || (tsNext[ch] > (UCHAR_MAX * 5) / 8); @@ -1669,7 +1672,7 @@ ExhaleEncoder::ExhaleEncoder (int32_t* const inputPcmData, unsigned ch m_mdstSignals[ch] = nullptr; m_scaleFacData[ch] = nullptr; m_specAnaCurr[ch] = 0; - //m_specAnaPrev[ch] = 0; + m_specFlatPrev[ch] = 0; m_tempAnaCurr[ch] = 0; m_tempAnaNext[ch] = 0; m_timeSignals[ch] = nullptr; diff --git a/src/lib/exhaleEnc.h b/src/lib/exhaleEnc.h index ba55c26..d739204 100644 --- a/src/lib/exhaleEnc.h +++ b/src/lib/exhaleEnc.h @@ -94,7 +94,7 @@ private: SfbQuantizer m_sfbQuantizer; // powerlaw quantization SpecAnalyzer m_specAnalyzer; // for spectral analysis uint32_t m_specAnaCurr[USAC_MAX_NUM_CHANNELS]; -//uint32_t m_specAnaPrev[USAC_MAX_NUM_CHANNELS]; + uint8_t m_specFlatPrev[USAC_MAX_NUM_CHANNELS]; #if !RESTRICT_TO_AAC SpecGapFiller m_specGapFiller;// for noise/gap filling #endif diff --git a/src/lib/tempAnalysis.cpp b/src/lib/tempAnalysis.cpp index 0b1ec2c..132025e 100644 --- a/src/lib/tempAnalysis.cpp +++ b/src/lib/tempAnalysis.cpp @@ -1,5 +1,5 @@ /* tempAnalysis.cpp - source file for class providing temporal analysis of PCM signals - * written by C. R. Helmrich, last modified in 2019 - see License.htm for legal notices + * written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices * * The copyright in this software is being made available under a Modified BSD-Style License * and comes with ABSOLUTELY NO WARRANTY. This software may be subject to other third- @@ -247,6 +247,23 @@ unsigned TempAnalyzer::temporalAnalysis (const int32_t* const timeSignals[USAC_M sumAbsPpR = sumAbsValR; // right side pLagBestR = pLag; } +#if 1 // TA_MORE_PITCH_TESTS + if (pLagBestR > halfFrameOffset) // try ½ + { + pLag = pLagBestR >> 1; + pSgn = (((chSig[maxAbsIdxR] - chSigM1[maxAbsIdxR] > 0) && (chSig[maxAbsIdxR-pLag] - chSigM1[maxAbsIdxR-pLag] < 0)) || + ((chSig[maxAbsIdxR] - chSigM1[maxAbsIdxR] < 0) && (chSig[maxAbsIdxR-pLag] - chSigM1[maxAbsIdxR-pLag] > 0)) ? -1 : 1); + if ((sumAbsValL = applyPitchPred (chSig, halfFrameOffset, pLag, pSgn)) < sumAbsPpL) + { + sumAbsPpL = sumAbsValL; // left side + } + if ((sumAbsValR = applyPitchPred (chSig + halfFrameOffset, halfFrameOffset, pLag, pSgn)) < sumAbsPpR) + { + sumAbsPpR = sumAbsValR; // right side + pLagBestR = pLag; + } + } +#endif // convert L1 norms into average values sumAbsHpL = (sumAbsHpL + unsigned (halfFrameOffset >> 1)) / unsigned (halfFrameOffset); diff --git a/src/lib/tempAnalysis.h b/src/lib/tempAnalysis.h index b654390..5fa86b5 100644 --- a/src/lib/tempAnalysis.h +++ b/src/lib/tempAnalysis.h @@ -1,5 +1,5 @@ /* tempAnalysis.h - header file for class providing temporal analysis of PCM signals - * written by C. R. Helmrich, last modified in 2019 - see License.htm for legal notices + * written by C. R. Helmrich, last modified in 2020 - see License.htm for legal notices * * The copyright in this software is being made available under a Modified BSD-Style License * and comes with ABSOLUTELY NO WARRANTY. This software may be subject to other third- @@ -15,7 +15,7 @@ // constants, experimental macros #define TA_EPS 4096 -#define TA_MORE_PITCH_TESTS 0 +#define TA_MORE_PITCH_TESTS 1 // temporal signal analysis class class TempAnalyzer