winamp/Src/vlb/channelinfo.cpp

262 lines
5.7 KiB
C++

/* $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] ;
}