/* $Header: /cvs/root/winamp/vlb/channelinfo.cpp,v 1.1 2009/04/28 20:21:08 audiodsp Exp $ */ /***************************************************************************\ * * Copyright 2000-2002 Dolby Laboratories, Inc. All Rights * Reserved. Do not copy. Do not distribute. * Confidential information. * * (C) copyright Fraunhofer - IIS (1998) * All Rights Reserved * * filename: channelinfo.cpp * project : MPEG-2 AAC Decoder * contents/description: independent channel stream info object * \***************************************************************************/ #include "channelinfo.h" #include "streaminfo.h" // // // CChannelInfo wraps ics_info() CChannelInfo::CChannelInfo () : m_IcsReservedBit (1), m_WindowSequence (2), m_WindowShape (1), m_ScaleFactorGrouping (7), m_PredictorDataPresent (1) #ifdef MAIN_PROFILE , m_PredictorReset (1), m_PredictorResetGroupNumber (5) #endif { m_Valid = false ; m_TotalSfBands = 0 ; } CChannelInfo::~CChannelInfo () { } int CChannelInfo::GetProfile (void) const { return m_Profile ; } bool CChannelInfo::IsValid (void) const { return m_Valid ; } void CChannelInfo::Reset (const CStreamInfo &si) { m_Valid = false ; m_TotalSfBands = 0 ; m_SamplingRateIndex = si.GetSamplingRateIndex () ; m_Profile = si.GetProfile () ; } bool CChannelInfo::IsLongBlock (void) const { return (m_WindowSequence != EightShortSequence) ; } bool CChannelInfo::IsShortBlock (void) const { return (m_WindowSequence == EightShortSequence) ; } bool CChannelInfo::IsMainProfile (void) const { return (m_Profile == ProfileMain) ; } int CChannelInfo::GetWindowsPerFrame (void) const { return (m_WindowSequence == EightShortSequence) ? 8 : 1 ; } int CChannelInfo::GetWindowSequence (void) const { return m_WindowSequence ; } int CChannelInfo::GetWindowGroups (void) const { return m_WindowGroups ; } int CChannelInfo::GetWindowGroupLength (int index) const { return m_WindowGroupLength [index] ; } // scale factor band indices const int *CChannelInfo::GetScaleFactorBandOffsets (void) const { if (IsLongBlock ()) { return m_SamplingRateInfoTable [m_SamplingRateIndex].ScaleFactorBands_Long ; } else { return m_SamplingRateInfoTable [m_SamplingRateIndex].ScaleFactorBands_Short ; } } int CChannelInfo::GetLastBin() { if (IsLongBlock()) { return m_SamplingRateInfoTable[m_SamplingRateIndex].ScaleFactorBands_Long[m_MaxSfBands]; } else { return m_SamplingRateInfoTable[m_SamplingRateIndex].ScaleFactorBands_Short[m_MaxSfBands]; } } int CChannelInfo::GetSamplingFrequency (void) const { return SamplingRateFromIndex (m_SamplingRateIndex) ; } int CChannelInfo::SamplingRateFromIndex (int index) { return m_SamplingRateInfoTable [index].SamplingFrequency ; } #ifdef MAIN_PROFILE int CChannelInfo::GetMaximumPredictionBands (void) const { return m_SamplingRateInfoTable [m_SamplingRateIndex].MaximumPredictionBands ; } void CChannelInfo::DeactivatePrediction (int band) { if (band < GetMaximumPredictionBands ()) { m_PredictionUsed [band] = false ; } } #endif void CChannelInfo::Read (CDolbyBitStream &bs) { m_IcsReservedBit.Read (bs) ; m_WindowSequence.Read (bs) ; m_WindowShape.Read (bs) ; #ifdef ONLY_SINE_WINDOW if (m_WindowShape == 1) throw EUnsupportedWindowShape () ; #endif if (IsLongBlock ()) { m_TotalSfBands = m_SamplingRateInfoTable [m_SamplingRateIndex].NumberOfScaleFactorBands_Long ; m_MaxSfBands.Read (bs, 6) ; if (m_PredictorDataPresent.Read (bs)) { #ifdef MAIN_PROFILE if (m_PredictorReset.Read (bs)) { m_PredictorResetGroupNumber.Read (bs) ; if ((m_PredictorResetGroupNumber < 1) || (m_PredictorResetGroupNumber > 30)) { throw EInvalidPredictorReset () ; } } int maxpred = (GetScaleFactorBandsTransmitted () < GetMaximumPredictionBands ()) ? GetScaleFactorBandsTransmitted () : GetMaximumPredictionBands () ; for (int band = 0 ; band < maxpred ; band++) { m_PredictionUsed [band] = bs.Get (1) ? true : false ; } #else throw EIllegalProfile(); #endif } m_WindowGroups = 1 ; m_WindowGroupLength [0] = 1 ; } else { m_TotalSfBands = m_SamplingRateInfoTable [m_SamplingRateIndex].NumberOfScaleFactorBands_Short ; m_MaxSfBands.Read (bs, 4) ; m_ScaleFactorGrouping.Read (bs) ; // // // expand group lengths m_WindowGroups = 0 ; for (int i = 0 ; i < 7 ; i++) { int mask = 1 << (6 - i) ; m_WindowGroupLength [i] = 1 ; if (m_ScaleFactorGrouping & mask) { m_WindowGroupLength [m_WindowGroups]++ ; } else { m_WindowGroups++ ; } } // loop runs to i < 7 only m_WindowGroupLength [7] = 1 ; m_WindowGroups++ ; } m_Valid = true ; } int CChannelInfo::GetMaximumTnsBands (void) const { static const int tns_max_bands_tbl [12][4] = { /* entry for each sampling rate * 1 Main/LC long window * 2 Main/LC short window * 3 SSR long window * 4 SSR short window */ { 31, 9, 28, 7 }, /* 96000 */ { 31, 9, 28, 7 }, /* 88200 */ { 34, 10, 27, 7 }, /* 64000 */ { 40, 14, 26, 6 }, /* 48000 */ { 42, 14, 26, 6 }, /* 44100 */ { 51, 14, 26, 6 }, /* 32000 */ { 46, 14, 29, 7 }, /* 24000 */ { 46, 14, 29, 7 }, /* 22050 */ { 42, 14, 23, 8 }, /* 16000 */ { 42, 14, 23, 8 }, /* 12000 */ { 42, 14, 23, 8 }, /* 11025 */ { 39, 14, 19, 7 }, /* 8000 */ } ; int i = IsLongBlock () ? 0 : 1 ; i += (GetProfile () == ProfileSSR) ? 2 : 0 ; return tns_max_bands_tbl [m_SamplingRateIndex][i] ; }