1#ifndef APE_START_FILTER_H
2#define APE_START_FILTER_H
3
4class CStartFilter
5{
6public:
7
8	CStartFilter()
9	{
10
11	}
12
13	~CStartFilter()
14	{
15
16
17	}
18
19	void Flush()
20	{
21		m_rbInputA.Flush();
22		m_rbInputB.Flush();
23
24		memset(m_aryMA, 0, sizeof(m_aryMA));
25		memset(m_aryMB, 0, sizeof(m_aryMB));
26
27		m_Stage1FilterA1.Flush();
28		m_Stage1FilterA2.Flush();
29		m_Stage1FilterA3.Flush();
30
31		m_Stage1FilterB1.Flush();
32		m_Stage1FilterB2.Flush();
33		m_Stage1FilterB3.Flush();
34	}
35
36	void Compress(int & nA, int & nB)
37	{
38/*
39		nA = m_Stage1FilterA1.Compress(nA);
40		nA = m_Stage1FilterA2.Compress(nA);
41		nA = m_Stage1FilterA3.Compress(nA);
42
43		nB = m_Stage1FilterB1.Compress(nB);
44		nB = m_Stage1FilterB2.Compress(nB);
45		nB = m_Stage1FilterB3.Compress(nB);
46		return;
47//*/
48
49		nA = m_Stage1FilterA1.Compress(nA);
50		nA = m_Stage1FilterA2.Compress(nA);
51//		nA = m_Stage1FilterA3.Compress(nA);
52
53		nB = m_Stage1FilterB1.Compress(nB);
54		nB = m_Stage1FilterB2.Compress(nB);
55
56		//int nTemp = nA; nA = nB; nB = nTemp;
57//		nB = m_Stage1FilterB3.Compress(nB);
58
59//		nA = nA - nB;
60//		nB = nB + (nA / 2);
61
62
63//		return;
64
65		m_rbInputA[0] = nA; m_rbInputB[0] = nB;
66
67		{
68			int nPrediction1 = m_rbInputA[-1];
69			int nPrediction2 = m_rbInputA[-2];
70			int nPrediction3 = m_rbInputA[-1] - m_rbInputA[-2];
71			int nPrediction4 = m_rbInputB[-1];
72
73			int nTotalPrediction = (nPrediction1 * m_aryMA[0]) + (nPrediction2 * m_aryMA[1])
74				+ (nPrediction3  * m_aryMA[2]) + (nPrediction4 * m_aryMA[3]);
75			int nOutput = nA - (nTotalPrediction >> 13);
76
77			if (nOutput > 0)
78			{
79				m_aryMA[0] -= 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
80				m_aryMA[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
81				m_aryMA[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
82				m_aryMA[3] -= 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
83			}
84			else if (nOutput < 0)
85			{
86				m_aryMA[0] += 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
87				m_aryMA[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
88				m_aryMA[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
89				m_aryMA[3] += 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
90			}
91
92			nA = nOutput;
93		}
94		{
95			int nPrediction1 = m_rbInputB[-1];
96			int nPrediction2 = m_rbInputB[-2];
97			int nPrediction3 = 0;//m_rbInputB[-1] - m_rbInputB[-2];
98			int nPrediction4 = m_rbInputA[0];
99
100			int nTotalPrediction = (nPrediction1 * m_aryMB[0]) + (nPrediction2 * m_aryMB[1])
101				+ (nPrediction3  * m_aryMB[2]) + (nPrediction4 * m_aryMB[3]);
102			int nOutput = nB - (nTotalPrediction >> 13);
103
104			if (nOutput > 0)
105			{
106				m_aryMB[0] -= 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
107				m_aryMB[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
108				m_aryMB[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
109				m_aryMB[3] -= 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
110			}
111			else if (nOutput < 0)
112			{
113				m_aryMB[0] += 2*((nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0);
114				m_aryMB[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
115				m_aryMB[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
116				m_aryMB[3] += 1*((nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0);
117			}
118
119			nB = nOutput;
120		}
121
122
123		m_rbInputA.IncrementSafe();
124		m_rbInputB.IncrementSafe();
125
126
127/*
128//		nInput = m_Filter1.Compress(nInput);
129
130		m_rbInput[0] = nInput;
131
132		int nPrediction1 = m_rbInput[-1];
133		int nPrediction2 = (2 * m_rbInput[-1]) - m_rbInput[-2];
134		int nPrediction3 = m_rbInput[-1] - m_rbInput[-2];
135		int nPrediction4 = m_nLastOutput;
136
137		int nTotalPrediction = ((nPrediction1) * m_aryM[0]) + (nPrediction2 * m_aryM[1])
138			+ ((nPrediction3 >> 1) * m_aryM[2]) + (nPrediction4 * m_aryM[3]);
139		int nOutput = nInput - (nTotalPrediction >> 13);
140
141		if (nOutput > 0)
142		{
143			m_aryM[0] -= (nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0;
144			m_aryM[1] -= (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
145			m_aryM[2] -= (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
146			m_aryM[3] -= (nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0;
147		}
148		else if (nOutput < 0)
149		{
150			m_aryM[0] += (nPrediction1) ? ((nPrediction1 >> 30) & 2) - 1 : 0;
151			m_aryM[1] += (nPrediction2) ? ((nPrediction2 >> 30) & 2) - 1 : 0;
152			m_aryM[2] += (nPrediction3) ? ((nPrediction3 >> 30) & 2) - 1 : 0;
153			m_aryM[3] += (nPrediction4) ? ((nPrediction4 >> 30) & 2) - 1 : 0;
154		}
155
156		m_nLastOutput = nOutput;
157		m_rbInput.IncrementSafe();
158
159		return nOutput;
160		//*/
161	}
162
163protected:
164
165	CScaledFirstOrderFilter<31, 5> m_Stage1FilterA1;
166	CScaledFirstOrderFilter<24, 5> m_Stage1FilterA2;
167	CScaledFirstOrderFilter<7, 5> m_Stage1FilterA3;
168
169	CScaledFirstOrderFilter<31, 5> m_Stage1FilterB1;
170	CScaledFirstOrderFilter<24, 5> m_Stage1FilterB2;
171	CScaledFirstOrderFilter<7, 5> m_Stage1FilterB3;
172
173	CRollBufferFast<int, 256, 4> m_rbInputA;
174	CRollBufferFast<int, 256, 4> m_rbInputB;
175	int m_aryMA[8]; int m_aryMB[8];
176};
177
178#endif // #ifndef APE_START_FILTER_H
179