Flan
CDSPHBUpsampler.h
Go to the documentation of this file.
1 //$ nobt
2 //$ nocpp
3 
15 #ifndef R8B_CDSPHBUPSAMPLER_INCLUDED
16 #define R8B_CDSPHBUPSAMPLER_INCLUDED
17 
18 #include "CDSPProcessor.h"
19 
20 namespace r8b {
21 
31 {
32 public:
43  static void getHBFilter( const double ReqAtten, const int SteepIndex,
44  const double*& flt, int& fltt, double& att )
45  {
46  static const int FltCount = 11;
47  static const double HBKernel_4[ 4 ] = { // att -64.9241 dB, frac 4.0
48  6.1073830069265711e-001, -1.4463982571471876e-001,
49  4.1136036923118187e-002, -7.4740105856914872e-003 };
50  static const double HBKernel_5[ 5 ] = { // att -87.4775 dB, frac 4.0
51  6.1553054142504338e-001, -1.5591352339398118e-001,
52  5.2404802661298266e-002, -1.4230574348726146e-002,
53  2.2457593805377831e-003 };
54  static const double HBKernel_6[ 6 ] = { // att -104.5154 dB, frac 4.0
55  6.1883766561934184e-001, -1.6396282655874558e-001,
56  6.1104571279325129e-002, -2.0317756445217543e-002,
57  5.0264527466018826e-003, -6.9392938429507279e-004 };
58  static const double HBKernel_7[ 7 ] = { // att -120.6199 dB, frac 4.0
59  6.2125313688727779e-001, -1.6999763849273491e-001,
60  6.8014108060738196e-002, -2.5679821316697125e-002,
61  7.9798828249699784e-003, -1.7871060154498470e-003,
62  2.1836606459564009e-004 };
63  static const double HBKernel_8[ 8 ] = { // att -136.5151 dB, frac 4.0
64  6.2309299085367287e-001, -1.7468969193368433e-001,
65  7.3628746444973150e-002, -3.0378268550055314e-002,
66  1.0908085227657214e-002, -3.1287343330312556e-003,
67  6.3632014609722092e-004, -6.9597139145649502e-005 };
68  static const double HBKernel_9[ 9 ] = { // att -152.3240 dB, frac 4.0
69  6.2454069594794803e-001, -1.7844303649890664e-001,
70  7.8279410808762842e-002, -3.4501119561829857e-002,
71  1.3717889826645487e-002, -4.6090109007760798e-003,
72  1.2192752061406873e-003, -2.2647618541786664e-004,
73  2.2395554542567748e-005 };
74  static const double HBKernel_10[ 10 ] = { // att -168.0859 dB, frac 4.0
75  6.2570883988448611e-001, -1.8151274643053061e-001,
76  8.2191863294185458e-002, -3.8131779329357615e-002,
77  1.6367492549512565e-002, -6.1530178832078578e-003,
78  1.9277693942420303e-003, -4.7165916432255402e-004,
79  8.0491894752808465e-005, -7.2581515842465856e-006 };
80  static const double HBKernel_11[ 11 ] = { // att -183.7962 dB, frac 4.0
81  6.2667167706646965e-001, -1.8407153341833782e-001,
82  8.5529995600327216e-002, -4.1346831452173063e-002,
83  1.8844831683400131e-002, -7.7125170314919214e-003,
84  2.7268674834296570e-003, -7.9745028391855826e-004,
85  1.8116344571770699e-004, -2.8569149678673122e-005,
86  2.3667021922861879e-006 };
87  static const double HBKernel_12[ 12 ] = { // att -199.4768 dB, frac 4.0
88  6.2747849729182659e-001, -1.8623616781335248e-001,
89  8.8409755856508648e-002, -4.4207468780136254e-002,
90  2.1149175912217915e-002, -9.2551508154301194e-003,
91  3.5871562052326249e-003, -1.1923167600753576e-003,
92  3.2627812001613326e-004, -6.9106902008709490e-005,
93  1.0122897772888322e-005, -7.7531878091292963e-007 };
94  static const double HBKernel_13[ 13 ] = { // att -215.1364 dB, frac 4.0
95  6.2816416238782957e-001, -1.8809076918442266e-001,
96  9.0918539368474965e-002, -4.6765502172995604e-002,
97  2.3287520069933797e-002, -1.0760626940880943e-002,
98  4.4853921118213676e-003, -1.6438774496992904e-003,
99  5.1441308429384374e-004, -1.3211724349740752e-004,
100  2.6191316362108199e-005, -3.5802424384280469e-006,
101  2.5491272423372411e-007 };
102  static const double HBKernel_14[ 14 ] = { // att -230.7526 dB, frac 4.0
103  6.2875473147254901e-001, -1.8969942008858576e-001,
104  9.3126095475258408e-002, -4.9067252227455962e-002,
105  2.5273009767563311e-002, -1.2218646838258702e-002,
106  5.4048946497798353e-003, -2.1409921992386689e-003,
107  7.4250304371305991e-004, -2.1924546773651068e-004,
108  5.3015823597863675e-005, -9.8743070771832892e-006,
109  1.2650397198764347e-006, -8.4146728313072455e-008 };
110  static const double FltAttens[ FltCount ] = {
111  64.9241, 87.4775, 104.5154, 120.6199, 136.5151, 152.3240,
112  168.0859, 183.7962, 199.4768, 215.1364, 230.7526 };
113  static const double* const FltPtrs[ FltCount ] = { HBKernel_4,
114  HBKernel_5, HBKernel_6, HBKernel_7, HBKernel_8, HBKernel_9,
115  HBKernel_10, HBKernel_11, HBKernel_12, HBKernel_13,
116  HBKernel_14 };
117 
118  static const int FltCountB = 7; // 0.125
119  static const double HBKernel_2b[ 2 ] = { // StopAtten = -46.2556 dB
120  5.6965643437574798e-001, -7.0243561190601822e-002 };
121  static const double HBKernel_3b[ 3 ] = { // StopAtten = -93.6536 dB
122  5.9040785316467748e-001, -1.0462338733801557e-001,
123  1.4234900265846395e-002 };
124  static const double HBKernel_4b[ 4 ] = { // StopAtten = -123.4514 dB
125  6.0140277542879073e-001, -1.2564483854573050e-001,
126  2.7446500598030887e-002, -3.2051079559036744e-003 };
127  static const double HBKernel_5b[ 5 ] = { // StopAtten = -152.4403 dB
128  6.0818642429044178e-001, -1.3981140187082763e-001,
129  3.8489164053787661e-002, -7.6218861795043225e-003,
130  7.5772358126258155e-004 };
131  static const double HBKernel_6b[ 6 ] = { // StopAtten = -181.2501 dB
132  6.1278392271870352e-001, -1.5000053763409249e-001,
133  4.7575323519283508e-002, -1.2320702806281281e-002,
134  2.1462442604041065e-003, -1.8425092396978648e-004 };
135  static const double HBKernel_7b[ 7 ] = { // StopAtten = -209.9472 dB
136  6.1610372237019151e-001, -1.5767891821295410e-001,
137  5.5089690570484962e-002, -1.6895755290596615e-002,
138  3.9416641999499014e-003, -6.0603620400878633e-004,
139  4.5632598748568398e-005 };
140  static const double HBKernel_8b[ 8 ] = { // StopAtten = -238.5612 dB
141  6.1861282849648180e-001, -1.6367179296640288e-001,
142  6.1369859727781417e-002, -2.1184465440918565e-002,
143  5.9623352367661475e-003, -1.2483096884685629e-003,
144  1.7099294398059683e-004, -1.1448310399897466e-005 };
145  static const double FltAttensB[ FltCountB ] = {
146  46.2556, 93.6536, 123.4514, 152.4403, 181.2501, 209.9472,
147  238.5612 };
148  static const double* const FltPtrsB[ FltCountB ] = { HBKernel_2b,
149  HBKernel_3b, HBKernel_4b, HBKernel_5b, HBKernel_6b, HBKernel_7b,
150  HBKernel_8b };
151 
152  static const int FltCountC = 5; // 0.0625
153  static const double HBKernel_2c[ 2 ] = { // StopAtten = -87.9438 dB
154  5.6430278013478086e-001, -6.4338068855764208e-002 };
155  static const double HBKernel_3c[ 3 ] = { // StopAtten = -130.8862 dB
156  5.8706402915553113e-001, -9.9362380958695873e-002,
157  1.2298637065878193e-002 };
158  static const double HBKernel_4c[ 4 ] = { // StopAtten = -172.3191 dB
159  5.9896586135108265e-001, -1.2111680603660968e-001,
160  2.4763118077755664e-002, -2.6121758134936002e-003 };
161  static const double HBKernel_5c[ 5 ] = { // StopAtten = -213.4984 dB
162  6.0626808278478261e-001, -1.3588224019070938e-001,
163  3.5544305138258458e-002, -6.5127022013993230e-003,
164  5.8255449020627736e-004 };
165  static const double HBKernel_6c[ 6 ] = { // StopAtten = -254.5179 dB
166  6.1120171157732273e-001, -1.4654486624691154e-001,
167  4.4582957343679119e-002, -1.0840542911916273e-002,
168  1.7343703931622656e-003, -1.3363015552414481e-004 };
169  static const double FltAttensC[ FltCountC ] = {
170  87.9438, 130.8862, 172.3191, 213.4984, 254.5179 };
171  static const double* const FltPtrsC[ FltCountC ] = { HBKernel_2c,
172  HBKernel_3c, HBKernel_4c, HBKernel_5c, HBKernel_6c };
173 
174  static const int FltCountD = 3; // 0.03125
175  static const double HBKernel_2d[ 2 ] = { // StopAtten = -113.1456 dB
176  5.6295152180538044e-001, -6.2953706070191726e-002 };
177  static const double HBKernel_3d[ 3 ] = { // StopAtten = -167.1446 dB
178  5.8621968728761675e-001, -9.8080551656624410e-002,
179  1.1860868762030571e-002 };
180  static const double HBKernel_4d[ 4 ] = { // StopAtten = -220.6519 dB
181  5.9835028661892165e-001, -1.1999986095168852e-001,
182  2.4132530901858028e-002, -2.4829565783680927e-003 };
183  static const double FltAttensD[ FltCountD ] = {
184  113.1456, 167.1446, 220.6519 };
185  static const double* const FltPtrsD[ FltCountD ] = { HBKernel_2d,
186  HBKernel_3d, HBKernel_4d };
187 
188  static const int FltCountE = 4; // 0.015625
189  static const double HBKernel_1e[ 1 ] = { // StopAtten = -60.9962 dB
190  5.0030136284718241e-001 };
191  static const double HBKernel_2e[ 2 ] = { // StopAtten = -137.3130 dB
192  5.6261293163934145e-001, -6.2613067826625832e-002 };
193  static const double HBKernel_3e[ 3 ] = { // StopAtten = -203.2997 dB
194  5.8600808139033378e-001, -9.7762185874608526e-002,
195  1.1754104552667852e-002 };
196  static const double HBKernel_4e[ 4 ] = { // StopAtten = -268.8561 dB
197  5.9819599535791312e-001, -1.1972157884617740e-001,
198  2.3977307400990484e-002, -2.4517239127622593e-003 };
199  static const double FltAttensE[ FltCountE ] = {
200  60.9962, 137.3130, 203.2997, 268.8561 };
201  static const double* const FltPtrsE[ FltCountE ] = { HBKernel_1e,
202  HBKernel_2e, HBKernel_3e, HBKernel_4e };
203 
204  static const int FltCountG = 3;
205  static const double HBKernel_1g[ 1 ] = { // att -93.9165 dB, frac 256.0
206  5.0001882524896712e-001 };
207  static const double HBKernel_2g[ 2 ] = { // att -185.4886 dB, frac 256.0
208  5.6250705922473820e-001, -6.2507059756319761e-002 };
209  static const double HBKernel_3g[ 3 ] = { // att -275.5531 dB, frac 256.0
210  5.8594191093025305e-001, -9.7662866644414148e-002,
211  1.1720955714177778e-002 };
212  static const double FltAttensG[ FltCountG ] = {
213  93.9165, 185.4886, 275.5531 };
214  static const double* const FltPtrsG[ FltCountG ] = { HBKernel_1g,
215  HBKernel_2g, HBKernel_3g };
216 
217  int k = 0;
218 
219  if( SteepIndex <= 0 )
220  {
221  while( k != FltCount - 1 && FltAttens[ k ] < ReqAtten )
222  {
223  k++;
224  }
225 
226  flt = FltPtrs[ k ];
227  fltt = 4 + k;
228  att = FltAttens[ k ];
229  }
230  else
231  if( SteepIndex == 1 )
232  {
233  while( k != FltCountB - 1 && FltAttensB[ k ] < ReqAtten )
234  {
235  k++;
236  }
237 
238  flt = FltPtrsB[ k ];
239  fltt = 2 + k;
240  att = FltAttensB[ k ];
241  }
242  else
243  if( SteepIndex == 2 )
244  {
245  while( k != FltCountC - 1 && FltAttensC[ k ] < ReqAtten )
246  {
247  k++;
248  }
249 
250  flt = FltPtrsC[ k ];
251  fltt = 2 + k;
252  att = FltAttensC[ k ];
253  }
254  else
255  if( SteepIndex == 3 )
256  {
257  while( k != FltCountD - 1 && FltAttensD[ k ] < ReqAtten )
258  {
259  k++;
260  }
261 
262  flt = FltPtrsD[ k ];
263  fltt = 2 + k;
264  att = FltAttensD[ k ];
265  }
266  else
267  if( SteepIndex == 4 || SteepIndex == 5 )
268  {
269  while( k != FltCountE - 1 && FltAttensE[ k ] < ReqAtten )
270  {
271  k++;
272  }
273 
274  flt = FltPtrsE[ k ];
275  fltt = 1 + k;
276  att = FltAttensE[ k ];
277  }
278  else
279  {
280  while( k != FltCountG - 1 && FltAttensG[ k ] < ReqAtten )
281  {
282  k++;
283  }
284 
285  flt = FltPtrsG[ k ];
286  fltt = 1 + k;
287  att = FltAttensG[ k ];
288  }
289  }
290 
301  static void getHBFilterThird( const double ReqAtten, const int SteepIndex,
302  const double*& flt, int& fltt, double& att )
303  {
304  static const int FltCount = 7;
305  static const double HBKernel_3[ 3 ] = { // att -75.0994 dB, frac 6.0
306  5.9381789425210385e-001, -1.1030344037819353e-001,
307  1.6601396044066741e-002 };
308  static const double HBKernel_4[ 4 ] = { // att -102.5310 dB, frac 6.0
309  6.0388679447131843e-001, -1.3043900369548017e-001,
310  3.0518777984447295e-002, -3.9738477033171900e-003 };
311  static const double HBKernel_5[ 5 ] = { // att -126.5360 dB, frac 6.0
312  6.1014115058940344e-001, -1.4393081816630204e-001,
313  4.1760642892854860e-002, -8.9692183234068596e-003,
314  9.9871340618369218e-004 };
315  static const double HBKernel_6[ 6 ] = { // att -150.1830 dB, frac 6.0
316  6.1439563420561982e-001, -1.5360187826939378e-001,
317  5.0840891346007507e-002, -1.4053648740740480e-002,
318  2.6771286587896391e-003, -2.5815816045721899e-004 };
319  static const double HBKernel_7[ 7 ] = { // att -173.7067 dB, frac 6.0
320  6.1747493476475102e-001, -1.6087373733655960e-001,
321  5.8263075644905349e-002, -1.8872408175697929e-002,
322  4.7421376553202421e-003, -8.0196529637661137e-004,
323  6.7964807425180754e-005 };
324  static const double HBKernel_8[ 8 ] = { // att -197.1454 dB, frac 6.0
325  6.1980610946074488e-001, -1.6654070574184196e-001,
326  6.4416567396953492e-002, -2.3307744316524541e-002,
327  6.9909157209589430e-003, -1.5871946236745982e-003,
328  2.4017727258609085e-004, -1.8125308111373566e-005 };
329  static const double HBKernel_9[ 9 ] = { // att -220.5199 dB, frac 6.0
330  6.2163188987470752e-001, -1.7108115412330563e-001,
331  6.9588371105224839e-002, -2.7339625869282957e-002,
332  9.2954473703765472e-003, -2.5537181861669997e-003,
333  5.2572296540671394e-004, -7.1813366796731157e-005,
334  4.8802392556669750e-006 };
335  static const double FltAttens[ FltCount ] = {
336  75.0994, 102.5310, 126.5360, 150.1830, 173.7067, 197.1454,
337  220.5199 };
338  static const double* const FltPtrs[ FltCount ] = { HBKernel_3,
339  HBKernel_4, HBKernel_5, HBKernel_6, HBKernel_7, HBKernel_8,
340  HBKernel_9 };
341 
342  static const int FltCountB = 5;
343  static const double HBKernel_2b[ 2 ] = { // att -75.4413 dB, frac 12.0
344  5.6569875353984056e-001, -6.5811416441328888e-002 };
345  static const double HBKernel_3b[ 3 ] = { // att -115.7198 dB, frac 12.0
346  5.8793612182667099e-001, -1.0070583248877137e-001,
347  1.2771337947163270e-002 };
348  static const double HBKernel_4b[ 4 ] = { // att -152.1528 dB, frac 12.0
349  5.9960155600859322e-001, -1.2228154335192955e-001,
350  2.5433718917658079e-002, -2.7537562530760588e-003 };
351  static const double HBKernel_5b[ 5 ] = { // att -188.2914 dB, frac 12.0
352  6.0676859170270769e-001, -1.3689667009297382e-001,
353  3.6288512627614941e-002, -6.7838855288962756e-003,
354  6.2345167652090897e-004 };
355  static const double HBKernel_6b[ 6 ] = { // att -224.2705 dB, frac 12.0
356  6.1161456377889145e-001, -1.4743902036519768e-001,
357  4.5344160828746795e-002, -1.1207372108402218e-002,
358  1.8328498006058664e-003, -1.4518194076022933e-004 };
359  static const double FltAttensB[ FltCountB ] = {
360  75.4413, 115.7198, 152.1528, 188.2914, 224.2705 };
361  static const double* const FltPtrsB[ FltCountB ] = { HBKernel_2b,
362  HBKernel_3b, HBKernel_4b, HBKernel_5b, HBKernel_6b };
363 
364  static const int FltCountC = 4;
365  static const double HBKernel_2c[ 2 ] = { // att -102.9806 dB, frac 24.0
366  5.6330232648142842e-001, -6.3309247177420730e-002 };
367  static const double HBKernel_3c[ 3 ] = { // att -152.1187 dB, frac 24.0
368  5.8643891113575064e-001, -9.8411593011501639e-002,
369  1.1972706651455891e-002 };
370  static const double HBKernel_4c[ 4 ] = { // att -200.6182 dB, frac 24.0
371  5.9851012364429712e-001, -1.2028885240905723e-001,
372  2.4294521088349529e-002, -2.5157924167197453e-003 };
373  static const double HBKernel_5c[ 5 ] = { // att -248.8728 dB, frac 24.0
374  6.0590922849004858e-001, -1.3515953371903033e-001,
375  3.5020856634677522e-002, -6.3256195330255094e-003,
376  5.5506812768978109e-004 };
377  static const double FltAttensC[ FltCountC ] = {
378  102.9806, 152.1187, 200.6182, 248.8728 };
379  static const double* const FltPtrsC[ FltCountC ] = { HBKernel_2c,
380  HBKernel_3c, HBKernel_4c, HBKernel_5c };
381 
382  static const int FltCountD = 4;
383  static const double HBKernel_1d[ 1 ] = { // att -48.6615 dB, frac 48.0
384  5.0053598654836240e-001 };
385  static const double HBKernel_2d[ 2 ] = { // att -127.3033 dB, frac 48.0
386  5.6270074379958679e-001, -6.2701174487726163e-002 };
387  static const double HBKernel_3d[ 3 ] = { // att -188.2989 dB, frac 48.0
388  5.8606296210257025e-001, -9.7844644764129421e-002,
389  1.1781683046197223e-002 };
390  static const double HBKernel_4d[ 4 ] = { // att -248.8578 dB, frac 48.0
391  5.9823601283411165e-001, -1.1979369067338455e-001,
392  2.4017459011435899e-002, -2.4597811725236445e-003 };
393  static const double FltAttensD[ FltCountD ] = {
394  48.6615, 127.3033, 188.2989, 248.8578 };
395  static const double* const FltPtrsD[ FltCountD ] = { HBKernel_1d,
396  HBKernel_2d, HBKernel_3d, HBKernel_4d };
397 
398  static const int FltCountE = 3;
399  static const double HBKernel_1e[ 1 ] = { // att -73.2782 dB, frac 96.0
400  5.0013388897382527e-001 };
401  static const double HBKernel_2e[ 2 ] = { // att -151.4076 dB, frac 96.0
402  5.6255019604318290e-001, -6.2550222932385172e-002 };
403  static const double HBKernel_3e[ 3 ] = { // att -224.4366 dB, frac 96.0
404  5.8596887233874539e-001, -9.7703321108182931e-002,
405  1.1734448775437802e-002 };
406  static const double FltAttensE[ FltCountE ] = {
407  73.2782, 151.4076, 224.4366 };
408  static const double* const FltPtrsE[ FltCountE ] = { HBKernel_1e,
409  HBKernel_2e, HBKernel_3e };
410 
411  static const int FltCountG = 3;
412  static const double HBKernel_1g[ 1 ] = { // att -101.2873 dB, frac 384.0
413  5.0000836666064941e-001 };
414  static const double HBKernel_2g[ 2 ] = { // att -199.5761 dB, frac 384.0
415  5.6250313744967606e-001, -6.2503137554676916e-002 };
416  static const double HBKernel_3g[ 3 ] = { // att -296.4833 dB, frac 384.0
417  5.8593945769687561e-001, -9.7659186594368730e-002,
418  1.1719728897494584e-002 };
419  static const double FltAttensG[ FltCountG ] = {
420  101.2873, 199.5761, 296.4833 };
421  static const double* const FltPtrsG[ FltCountG ] = { HBKernel_1g,
422  HBKernel_2g, HBKernel_3g };
423 
424  int k = 0;
425 
426  if( SteepIndex <= 0 )
427  {
428  while( k != FltCount - 1 && FltAttens[ k ] < ReqAtten )
429  {
430  k++;
431  }
432 
433  flt = FltPtrs[ k ];
434  fltt = 3 + k;
435  att = FltAttens[ k ];
436  }
437  else
438  if( SteepIndex == 1 )
439  {
440  while( k != FltCountB - 1 && FltAttensB[ k ] < ReqAtten )
441  {
442  k++;
443  }
444 
445  flt = FltPtrsB[ k ];
446  fltt = 2 + k;
447  att = FltAttensB[ k ];
448  }
449  else
450  if( SteepIndex == 2 )
451  {
452  while( k != FltCountC - 1 && FltAttensC[ k ] < ReqAtten )
453  {
454  k++;
455  }
456 
457  flt = FltPtrsC[ k ];
458  fltt = 2 + k;
459  att = FltAttensC[ k ];
460  }
461  else
462  if( SteepIndex == 3 )
463  {
464  while( k != FltCountD - 1 && FltAttensD[ k ] < ReqAtten )
465  {
466  k++;
467  }
468 
469  flt = FltPtrsD[ k ];
470  fltt = 1 + k;
471  att = FltAttensD[ k ];
472  }
473  else
474  if( SteepIndex == 4 || SteepIndex == 5 )
475  {
476  while( k != FltCountE - 1 && FltAttensE[ k ] < ReqAtten )
477  {
478  k++;
479  }
480 
481  flt = FltPtrsE[ k ];
482  fltt = 1 + k;
483  att = FltAttensE[ k ];
484  }
485  else
486  {
487  while( k != FltCountG - 1 && FltAttensG[ k ] < ReqAtten )
488  {
489  k++;
490  }
491 
492  flt = FltPtrsG[ k ];
493  fltt = 1 + k;
494  att = FltAttensG[ k ];
495  }
496  }
497 
512  CDSPHBUpsampler( const double ReqAtten, const int SteepIndex,
513  const bool IsThird, const double PrevLatency )
514  {
515  static const CConvolveFn FltConvFn[ 14 ] = {
516  &CDSPHBUpsampler :: convolve1, &CDSPHBUpsampler :: convolve2,
517  &CDSPHBUpsampler :: convolve3, &CDSPHBUpsampler :: convolve4,
518  &CDSPHBUpsampler :: convolve5, &CDSPHBUpsampler :: convolve6,
519  &CDSPHBUpsampler :: convolve7, &CDSPHBUpsampler :: convolve8,
520  &CDSPHBUpsampler :: convolve9, &CDSPHBUpsampler :: convolve10,
521  &CDSPHBUpsampler :: convolve11, &CDSPHBUpsampler :: convolve12,
522  &CDSPHBUpsampler :: convolve13, &CDSPHBUpsampler :: convolve14 };
523 
524  int fltt;
525  double att;
526 
527  if( IsThird )
528  {
529  getHBFilterThird( ReqAtten, SteepIndex, fltp, fltt, att );
530  }
531  else
532  {
533  getHBFilter( ReqAtten, SteepIndex, fltp, fltt, att );
534  }
535 
536  convfn = FltConvFn[ fltt - 1 ];
537  fll = fltt - 1;
538  fl2 = fltt;
539  flo = fll + fl2;
540 
541  LatencyFrac = PrevLatency * 2.0;
542  Latency = (int) LatencyFrac;
543  LatencyFrac -= Latency;
544 
545  R8BCONSOLE( "CDSPHBUpsampler: sti=%i third=%i taps=%i att=%.1f "
546  "io=2/1\n", SteepIndex, (int) IsThird, fltt, att );
547 
548  clear();
549  }
550 
551  virtual int getLatency() const
552  {
553  return( 0 );
554  }
555 
556  virtual double getLatencyFrac() const
557  {
558  return( LatencyFrac );
559  }
560 
561  virtual int getMaxOutLen( const int MaxInLen ) const
562  {
563  R8BASSERT( MaxInLen >= 0 );
564 
565  return( MaxInLen * 2 );
566  }
567 
568  virtual void clear()
569  {
570  LatencyLeft = Latency;
571  BufLeft = 0;
572  WritePos = 0;
573  ReadPos = BufLen - fll; // Set "read" position to
574  // account for filter's latency.
575 
576  memset( &Buf[ ReadPos ], 0, fll * sizeof( double ));
577  }
578 
579  virtual int process( double* ip, int l, double*& op0 )
580  {
581  R8BASSERT( l >= 0 );
582 
583  double* op = op0;
584 
585  while( l > 0 )
586  {
587  // Add new input samples to both halves of the ring buffer.
588 
589  const int b = min( min( l, BufLen - WritePos ),
590  BufLen - fll - BufLeft );
591 
592  double* const wp1 = Buf + WritePos;
593  memcpy( wp1, ip, b * sizeof( double ));
594 
595  if( WritePos < flo )
596  {
597  const int c = min( b, flo - WritePos );
598  memcpy( wp1 + BufLen, wp1, c * sizeof( double ));
599  }
600 
601  ip += b;
602  WritePos = ( WritePos + b ) & BufLenMask;
603  l -= b;
604  BufLeft += b;
605 
606  if( BufLeft > fl2 )
607  {
608  const int c = BufLeft - fl2;
609 
610  double* const opend = op + c + c;
611  ( *convfn )( op, opend, fltp, Buf + fll, ReadPos );
612 
613  op = opend;
614  BufLeft -= c;
615  }
616  }
617 
618  int ol = (int) ( op - op0 );
619 
620  if( LatencyLeft > 0 )
621  {
622  if( LatencyLeft >= ol )
623  {
624  LatencyLeft -= ol;
625  return( 0 );
626  }
627 
628  ol -= LatencyLeft;
629  op0 += LatencyLeft;
630  LatencyLeft = 0;
631  }
632 
633  return( ol );
634  }
635 
636 private:
637  static const int BufLenBits = 8;
638  static const int BufLen = 1 << BufLenBits;
645  static const int BufLenMask = BufLen - 1;
649  double Buf[ BufLen + 27 ];
652  const double* fltp;
655  int fll;
657  int fl2;
659  int flo;
661  int Latency;
663  double LatencyFrac;
665  int BufLeft;
667  int WritePos;
671  int ReadPos;
674  int LatencyLeft;
676  typedef void( *CConvolveFn )( double* op, double* const opend,
678  const double* const flt, const double* const rp0, int& ReadPos0 );
679  CConvolveFn convfn;
682 
684 #define R8BHBC1( fn ) \
685  static void fn( double* op, double* const opend, const double* const flt, \
686  const double* const rp0, int& ReadPos0 ) \
687  { \
688  int rpos = ReadPos0; \
689  while( op < opend ) \
690  { \
691  const double* const rp = rp0 + rpos; \
692  op[ 0 ] = rp[ 0 ]; \
693  op[ 1 ] =
694 
695 #define R8BHBC2 \
696  rpos = ( rpos + 1 ) & BufLenMask; \
697  op += 2; \
698  } \
699  ReadPos0 = rpos; \
700  }
701 
702  R8BHBC1( convolve1 )
703  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]);
704  R8BHBC2
705 
706  R8BHBC1( convolve2 )
707  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
708  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]);
709  R8BHBC2
710 
711  R8BHBC1( convolve3 )
712  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
713  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
714  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]);
715  R8BHBC2
716 
717  R8BHBC1( convolve4 )
718  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
719  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
720  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
721  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]);
722  R8BHBC2
723 
724  R8BHBC1( convolve5 )
725  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
726  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
727  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
728  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
729  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]);
730  R8BHBC2
731 
732  R8BHBC1( convolve6 )
733  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
734  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
735  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
736  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
737  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
738  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]);
739  R8BHBC2
740 
741  R8BHBC1( convolve7 )
742  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
743  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
744  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
745  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
746  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
747  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
748  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]);
749  R8BHBC2
750 
751  R8BHBC1( convolve8 )
752  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
753  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
754  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
755  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
756  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
757  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
758  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
759  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]);
760  R8BHBC2
761 
762  R8BHBC1( convolve9 )
763  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
764  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
765  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
766  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
767  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
768  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
769  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
770  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]) +
771  flt[ 8 ] * ( rp[ 9 ] + rp[ -8 ]);
772  R8BHBC2
773 
774  R8BHBC1( convolve10 )
775  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
776  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
777  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
778  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
779  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
780  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
781  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
782  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]) +
783  flt[ 8 ] * ( rp[ 9 ] + rp[ -8 ]) +
784  flt[ 9 ] * ( rp[ 10 ] + rp[ -9 ]);
785  R8BHBC2
786 
787  R8BHBC1( convolve11 )
788  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
789  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
790  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
791  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
792  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
793  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
794  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
795  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]) +
796  flt[ 8 ] * ( rp[ 9 ] + rp[ -8 ]) +
797  flt[ 9 ] * ( rp[ 10 ] + rp[ -9 ]) +
798  flt[ 10 ] * ( rp[ 11 ] + rp[ -10 ]);
799  R8BHBC2
800 
801  R8BHBC1( convolve12 )
802  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
803  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
804  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
805  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
806  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
807  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
808  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
809  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]) +
810  flt[ 8 ] * ( rp[ 9 ] + rp[ -8 ]) +
811  flt[ 9 ] * ( rp[ 10 ] + rp[ -9 ]) +
812  flt[ 10 ] * ( rp[ 11 ] + rp[ -10 ]) +
813  flt[ 11 ] * ( rp[ 12 ] + rp[ -11 ]);
814  R8BHBC2
815 
816  R8BHBC1( convolve13 )
817  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
818  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
819  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
820  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
821  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
822  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
823  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
824  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]) +
825  flt[ 8 ] * ( rp[ 9 ] + rp[ -8 ]) +
826  flt[ 9 ] * ( rp[ 10 ] + rp[ -9 ]) +
827  flt[ 10 ] * ( rp[ 11 ] + rp[ -10 ]) +
828  flt[ 11 ] * ( rp[ 12 ] + rp[ -11 ]) +
829  flt[ 12 ] * ( rp[ 13 ] + rp[ -12 ]);
830  R8BHBC2
831 
832  R8BHBC1( convolve14 )
833  flt[ 0 ] * ( rp[ 1 ] + rp[ 0 ]) +
834  flt[ 1 ] * ( rp[ 2 ] + rp[ -1 ]) +
835  flt[ 2 ] * ( rp[ 3 ] + rp[ -2 ]) +
836  flt[ 3 ] * ( rp[ 4 ] + rp[ -3 ]) +
837  flt[ 4 ] * ( rp[ 5 ] + rp[ -4 ]) +
838  flt[ 5 ] * ( rp[ 6 ] + rp[ -5 ]) +
839  flt[ 6 ] * ( rp[ 7 ] + rp[ -6 ]) +
840  flt[ 7 ] * ( rp[ 8 ] + rp[ -7 ]) +
841  flt[ 8 ] * ( rp[ 9 ] + rp[ -8 ]) +
842  flt[ 9 ] * ( rp[ 10 ] + rp[ -9 ]) +
843  flt[ 10 ] * ( rp[ 11 ] + rp[ -10 ]) +
844  flt[ 11 ] * ( rp[ 12 ] + rp[ -11 ]) +
845  flt[ 12 ] * ( rp[ 13 ] + rp[ -12 ]) +
846  flt[ 13 ] * ( rp[ 14 ] + rp[ -13 ]);
847  R8BHBC2
848 
849 #undef R8BHBC1
850 #undef R8BHBC2
851 };
852 
853 // ---------------------------------------------------------------------------
854 
855 } // namespace r8b
856 
857 #endif // R8B_CDSPHBUPSAMPLER_INCLUDED
static void getHBFilterThird(const double ReqAtten, const int SteepIndex, const double *&flt, int &fltt, double &att)
Function that provides filter data for various steepness indices and attenuations.
Definition: CDSPHBUpsampler.h:301
#define R8BCONSOLE(...)
Console output macro, used to output various resampler status strings, including filter design parame...
Definition: r8bconf.h:85
Half-band upsampling class.
Definition: CDSPHBUpsampler.h:30
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions.
Definition: r8bconf.h:72
virtual double getLatencyFrac() const
Definition: CDSPHBUpsampler.h:556
virtual void clear()
Function clears (resets) the state of *this object and returns it to the state after construction...
Definition: CDSPHBUpsampler.h:568
The base virtual class for DSP processing algorithms.
virtual int getLatency() const
Definition: CDSPHBUpsampler.h:551
CDSPHBUpsampler(const double ReqAtten, const int SteepIndex, const bool IsThird, const double PrevLatency)
Constructor initalizes the half-band upsampler.
Definition: CDSPHBUpsampler.h:512
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1118
static void getHBFilter(const double ReqAtten, const int SteepIndex, const double *&flt, int &fltt, double &att)
Function that provides filter data for various steepness indices and attenuations.
Definition: CDSPHBUpsampler.h:43
virtual int process(double *ip, int l, double *&op0)
Function performs DSP processing.
Definition: CDSPHBUpsampler.h:579
The base virtual class for DSP processing algorithms.
Definition: CDSPProcessor.h:31
virtual int getMaxOutLen(const int MaxInLen) const
Definition: CDSPHBUpsampler.h:561
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21