#ifndef APE_START_FILTER_H
#define APE_START_FILTER_H
class CStartFilter
{
public:
CStartFilter()
{
}
~CStartFilter()
{
}
void Flush()
{
m_rbInputA.Flush();
m_rbInputB.Flush();
memset(m_aryMA, 0, sizeof(m_aryMA));
memset(m_aryMB, 0, sizeof(m_aryMB));
m_Stage1FilterA1.Flush();
m_Stage1FilterA2.Flush();
m_Stage1FilterA3.Flush();
m_Stage1FilterB1.Flush();
m_Stage1FilterB2.Flush();
m_Stage1FilterB3.Flush();
}
void Compress(int & nA, int & nB)
{
nA = m_Stage1FilterA1.Compress(nA);
nA = m_Stage1FilterA2.Compress(nA);
nB = m_Stage1FilterB1.Compress(nB);
nB = m_Stage1FilterB2.Compress(nB);
m_rbInputA[0] = nA; m_rbInputB[0] = nB;
{
int nPrediction1 = m_rbInputA[-1];
int nPrediction2 = m_rbInputA[-2];
int nPrediction3 = m_rbInputA[-1] - m_rbInputA[-2];
int nPrediction4 = m_rbInputB[-1];
int nTotalPrediction = (nPrediction1 * m_aryMA[0]) + (nPrediction2 * m_aryMA[1])
+ (nPrediction3 * m_aryMA[2]) + (nPrediction4 * m_aryMA[3]);
int nOutput = nA - (nTotalPrediction >> 13);
if (nOutput > 0)
{
m_aryMA[0] -= 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
m_aryMA[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
m_aryMA[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
m_aryMA[3] -= 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
}
else if (nOutput < 0)
{
m_aryMA[0] += 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
m_aryMA[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
m_aryMA[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
m_aryMA[3] += 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
}
nA = nOutput;
}
{
int nPrediction1 = m_rbInputB[-1];
int nPrediction2 = m_rbInputB[-2];
int nPrediction3 = 0;
int nPrediction4 = m_rbInputA[0];
int nTotalPrediction = (nPrediction1 * m_aryMB[0]) + (nPrediction2 * m_aryMB[1])
+ (nPrediction3 * m_aryMB[2]) + (nPrediction4 * m_aryMB[3]);
int nOutput = nB - (nTotalPrediction >> 13);
if (nOutput > 0)
{
m_aryMB[0] -= 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
m_aryMB[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
m_aryMB[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
m_aryMB[3] -= 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
}
else if (nOutput < 0)
{
m_aryMB[0] += 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
m_aryMB[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
m_aryMB[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
m_aryMB[3] += 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
}
nB = nOutput;
}
m_rbInputA.IncrementSafe();
m_rbInputB.IncrementSafe();
}
protected:
CScaledFirstOrderFilter<31, 5> m_Stage1FilterA1;
CScaledFirstOrderFilter<24, 5> m_Stage1FilterA2;
CScaledFirstOrderFilter<7, 5> m_Stage1FilterA3;
CScaledFirstOrderFilter<31, 5> m_Stage1FilterB1;
CScaledFirstOrderFilter<24, 5> m_Stage1FilterB2;
CScaledFirstOrderFilter<7, 5> m_Stage1FilterB3;
CRollBufferFast<int, 256, 4> m_rbInputA;
CRollBufferFast<int, 256, 4> m_rbInputB;
int m_aryMA[8]; int m_aryMB[8];
};
#endif