mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
261 lines
5.7 KiB
C++
261 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] ;
|
|
}
|