r8brain-free-src
High-quality pro audio sample rate converter library
Loading...
Searching...
No Matches
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
20namespace r8b {
21
31{
32public:
46 static void getHBFilter( const double ReqAtten, const int SteepIndex,
47 const double*& flt, int& fltt, double& att )
48 {
49 static const double HBKernel_4A[ 4 ] = { // -54.5176 dB, 4
50 6.1729335650971517e-001, -1.5963945620743250e-001,
51 5.5073370934086312e-002, -1.4603578989932850e-002,};
52 static const double HBKernel_5A[ 5 ] = { // -66.3075 dB, 4
53 6.2068807424902472e-001, -1.6827573634467302e-001,
54 6.5263016720721170e-002, -2.2483331611592005e-002,
55 5.2917326684281110e-003,};
56 static const double HBKernel_6A[ 6 ] = { // -89.5271 dB, 4
57 6.2187202340480707e-001, -1.7132842113816371e-001,
58 6.9019169178765674e-002, -2.5799728312695277e-002,
59 7.4880112525741666e-003, -1.2844465869952567e-003,};
60 static const double HBKernel_7A[ 7 ] = { // -105.2842 dB, 4
61 6.2354494135775851e-001, -1.7571220703702045e-001,
62 7.4529843603968457e-002, -3.0701736822442153e-002,
63 1.0716755639039573e-002, -2.7833422930759735e-003,
64 4.1118797093875510e-004,};
65 static const double HBKernel_8A[ 8 ] = { // -121.0063 dB, 4
66 6.2488363107953926e-001, -1.7924942606514119e-001,
67 7.9068155655640557e-002, -3.4907523415495731e-002,
68 1.3710256799907897e-002, -4.3991142586987933e-003,
69 1.0259190163889602e-003, -1.3278941979339359e-004,};
70 static const double HBKernel_9A[ 9 ] = { // -136.6982 dB, 4
71 6.2597763804021977e-001, -1.8216414325139055e-001,
72 8.2879104876726728e-002, -3.8563442248249404e-002,
73 1.6471530499739394e-002, -6.0489108881335227e-003,
74 1.7805283804140392e-003, -3.7533200112729561e-004,
75 4.3172840558735476e-005,};
76 static const double HBKernel_10A[ 10 ] = { // -152.3572 dB, 4
77 6.2688767582974092e-001, -1.8460766807559420e-001,
78 8.6128943000481864e-002, -4.1774474147006607e-002,
79 1.9014801985747346e-002, -7.6870397465866507e-003,
80 2.6264590175341853e-003, -7.1106660285478562e-004,
81 1.3645852036179345e-004, -1.4113888783332969e-005,};
82 static const double HBKernel_11A[ 11 ] = { // -183.7962 dB, 4
83 6.2667167706948146e-001, -1.8407153342635879e-001,
84 8.5529995610836046e-002, -4.1346831462361310e-002,
85 1.8844831691322637e-002, -7.7125170365394992e-003,
86 2.7268674860562087e-003, -7.9745028501057233e-004,
87 1.8116344606360795e-004, -2.8569149754241848e-005,
88 2.3667022010173616e-006,};
89 static const double HBKernel_12A[ 12 ] = { // -199.4768 dB, 4
90 6.2747849730367999e-001, -1.8623616784506747e-001,
91 8.8409755898467945e-002, -4.4207468821462342e-002,
92 2.1149175945115381e-002, -9.2551508371115209e-003,
93 3.5871562170822330e-003, -1.1923167653750219e-003,
94 3.2627812189920129e-004, -6.9106902511490413e-005,
95 1.0122897863125124e-005, -7.7531878906846174e-007,};
96 static const double HBKernel_13A[ 13 ] = { // -215.1364 dB, 4
97 6.2816416252367324e-001, -1.8809076955230414e-001,
98 9.0918539867353029e-002, -4.6765502683599310e-002,
99 2.3287520498995663e-002, -1.0760627245014184e-002,
100 4.4853922948425683e-003, -1.6438775426910800e-003,
101 5.1441312354764978e-004, -1.3211725685765050e-004,
102 2.6191319837779187e-005, -3.5802430606313093e-006,
103 2.5491278270628601e-007,};
104 static const double HBKernel_14A[ 14 ] = { // -230.7526 dB, 4
105 6.2875473120929948e-001, -1.8969941936903847e-001,
106 9.3126094480960403e-002, -4.9067251179869126e-002,
107 2.5273008851199916e-002, -1.2218646153393291e-002,
108 5.4048942085580280e-003, -2.1409919546078581e-003,
109 7.4250292812927973e-004, -2.1924542206832172e-004,
110 5.3015808983125091e-005, -9.8743034923598196e-006,
111 1.2650391141650221e-006, -8.4146674637474946e-008,};
112 static const int FltCountA = 11;
113 static const int FlttBaseA = 4;
114 static const double FltAttensA[ FltCountA ] = {
115 54.5176, 66.3075, 89.5271, 105.2842, 121.0063, 136.6982, 152.3572, 183.7962, 199.4768, 215.1364, 230.7526, };
116 static const double* const FltPtrsA[ FltCountA ] = {
117 HBKernel_4A, HBKernel_5A, HBKernel_6A, HBKernel_7A, HBKernel_8A, HBKernel_9A, HBKernel_10A, HBKernel_11A, HBKernel_12A, HBKernel_13A, HBKernel_14A, };
118 static const double HBKernel_2B[ 2 ] = { // -56.6007 dB, 8
119 5.7361525854329076e-001, -7.5092074924827903e-002,};
120 static const double HBKernel_3B[ 3 ] = { // -83.0295 dB, 8
121 5.9277038608066912e-001, -1.0851340190268854e-001,
122 1.5813570475513079e-002,};
123 static const double HBKernel_4B[ 4 ] = { // -123.4724 dB, 8
124 6.0140277542879617e-001, -1.2564483854574138e-001,
125 2.7446500598038322e-002, -3.2051079559057435e-003,};
126 static const double HBKernel_5B[ 5 ] = { // -152.4411 dB, 8
127 6.0818642429088932e-001, -1.3981140187175697e-001,
128 3.8489164054503623e-002, -7.6218861797853104e-003,
129 7.5772358130952392e-004,};
130 static const double HBKernel_6B[ 6 ] = { // -181.2501 dB, 8
131 6.1278392271464355e-001, -1.5000053762513338e-001,
132 4.7575323511364960e-002, -1.2320702802243476e-002,
133 2.1462442592348487e-003, -1.8425092381892940e-004,};
134 static const double HBKernel_7B[ 7 ] = { // -209.9472 dB, 8
135 6.1610372263478952e-001, -1.5767891882524138e-001,
136 5.5089691170294691e-002, -1.6895755656366061e-002,
137 3.9416643438213977e-003, -6.0603623791604668e-004,
138 4.5632602433393365e-005,};
139 static const double HBKernel_8B[ 8 ] = { // -238.5616 dB, 8
140 6.1861282914465976e-001, -1.6367179451225150e-001,
141 6.1369861342939716e-002, -2.1184466539006987e-002,
142 5.9623357510842061e-003, -1.2483098507454090e-003,
143 1.7099297537964702e-004, -1.1448313239478885e-005,};
144 static const int FltCountB = 7;
145 static const int FlttBaseB = 2;
146 static const double FltAttensB[ FltCountB ] = {
147 56.6007, 83.0295, 123.4724, 152.4411, 181.2501, 209.9472, 238.5616, };
148 static const double* const FltPtrsB[ FltCountB ] = {
149 HBKernel_2B, HBKernel_3B, HBKernel_4B, HBKernel_5B, HBKernel_6B, HBKernel_7B, HBKernel_8B, };
150 static const double HBKernel_2C[ 2 ] = { // -89.0473 dB, 16
151 5.6430278013478008e-001, -6.4338068855763375e-002,};
152 static const double HBKernel_3C[ 3 ] = { // -130.8951 dB, 16
153 5.8706402915551448e-001, -9.9362380958670449e-002,
154 1.2298637065869358e-002,};
155 static const double HBKernel_4C[ 4 ] = { // -172.3192 dB, 16
156 5.9896586134984675e-001, -1.2111680603434927e-001,
157 2.4763118076458895e-002, -2.6121758132212989e-003,};
158 static const double HBKernel_5C[ 5 ] = { // -213.4984 dB, 16
159 6.0626808285230716e-001, -1.3588224032740795e-001,
160 3.5544305238309003e-002, -6.5127022377289654e-003,
161 5.8255449565950768e-004,};
162 static const double HBKernel_6C[ 6 ] = { // -254.5186 dB, 16
163 6.1120171263351242e-001, -1.4654486853757870e-001,
164 4.4582959299131253e-002, -1.0840543858123995e-002,
165 1.7343706485509962e-003, -1.3363018567985596e-004,};
166 static const int FltCountC = 5;
167 static const int FlttBaseC = 2;
168 static const double FltAttensC[ FltCountC ] = {
169 89.0473, 130.8951, 172.3192, 213.4984, 254.5186, };
170 static const double* const FltPtrsC[ FltCountC ] = {
171 HBKernel_2C, HBKernel_3C, HBKernel_4C, HBKernel_5C, HBKernel_6C, };
172 static const double HBKernel_1D[ 1 ] = { // -54.4754 dB, 32
173 5.0188900022775451e-001,};
174 static const double HBKernel_2D[ 2 ] = { // -113.2139 dB, 32
175 5.6295152180538044e-001, -6.2953706070191726e-002,};
176 static const double HBKernel_3D[ 3 ] = { // -167.1447 dB, 32
177 5.8621968728755036e-001, -9.8080551656524531e-002,
178 1.1860868761997080e-002,};
179 static const double HBKernel_4D[ 4 ] = { // -220.6519 dB, 32
180 5.9835028657163591e-001, -1.1999986086623511e-001,
181 2.4132530854004228e-002, -2.4829565686819706e-003,};
182 static const int FltCountD = 4;
183 static const int FlttBaseD = 1;
184 static const double FltAttensD[ FltCountD ] = {
185 54.4754, 113.2139, 167.1447, 220.6519, };
186 static const double* const FltPtrsD[ FltCountD ] = {
187 HBKernel_1D, HBKernel_2D, HBKernel_3D, HBKernel_4D, };
188 static const double HBKernel_1E[ 1 ] = { // -66.5391 dB, 64
189 5.0047102586416625e-001,};
190 static const double HBKernel_2E[ 2 ] = { // -137.3173 dB, 64
191 5.6261293163933568e-001, -6.2613067826620017e-002,};
192 static const double HBKernel_3E[ 3 ] = { // -203.2997 dB, 64
193 5.8600808139396787e-001, -9.7762185880067784e-002,
194 1.1754104554493029e-002,};
195 static const double HBKernel_4E[ 4 ] = { // -268.8550 dB, 64
196 5.9819599352772002e-001, -1.1972157555011861e-001,
197 2.3977305567947922e-002, -2.4517235455853992e-003,};
198 static const int FltCountE = 4;
199 static const int FlttBaseE = 1;
200 static const double FltAttensE[ FltCountE ] = {
201 66.5391, 137.3173, 203.2997, 268.8550, };
202 static const double* const FltPtrsE[ FltCountE ] = {
203 HBKernel_1E, HBKernel_2E, HBKernel_3E, HBKernel_4E, };
204 static const double HBKernel_1F[ 1 ] = { // -82.4633 dB, 128
205 5.0007530666642896e-001,};
206 static const double HBKernel_2F[ 2 ] = { // -161.4049 dB, 128
207 5.6252823610146030e-001, -6.2528244608044792e-002,};
208 static const double HBKernel_3F[ 3 ] = { // -239.4313 dB, 128
209 5.8595514744674237e-001, -9.7682725156791952e-002,
210 1.1727577711117231e-002,};
211 static const int FltCountF = 3;
212 static const int FlttBaseF = 1;
213 static const double FltAttensF[ FltCountF ] = {
214 82.4633, 161.4049, 239.4313, };
215 static const double* const FltPtrsF[ FltCountF ] = {
216 HBKernel_1F, HBKernel_2F, HBKernel_3F, };
217 static const double HBKernel_1G[ 1 ] = { // -94.5052 dB, 256
218 5.0001882524896712e-001,};
219 static const double HBKernel_2G[ 2 ] = { // -185.4886 dB, 256
220 5.6250705922479682e-001, -6.2507059756378394e-002,};
221 static const double HBKernel_3G[ 3 ] = { // -275.5501 dB, 256
222 5.8594191201187384e-001, -9.7662868266991207e-002,
223 1.1720956255134043e-002,};
224 static const int FltCountG = 3;
225 static const int FlttBaseG = 1;
226 static const double FltAttensG[ FltCountG ] = {
227 94.5052, 185.4886, 275.5501, };
228 static const double* const FltPtrsG[ FltCountG ] = {
229 HBKernel_1G, HBKernel_2G, HBKernel_3G, };
230
231 int k = 0;
232
233 if( SteepIndex <= 0 )
234 {
235 while( k != FltCountA - 1 && FltAttensA[ k ] < ReqAtten )
236 {
237 k++;
238 }
239
240 flt = FltPtrsA[ k ];
241 fltt = FlttBaseA + k;
242 att = FltAttensA[ k ];
243 }
244 else
245 if( SteepIndex == 1 )
246 {
247 while( k != FltCountB - 1 && FltAttensB[ k ] < ReqAtten )
248 {
249 k++;
250 }
251
252 flt = FltPtrsB[ k ];
253 fltt = FlttBaseB + k;
254 att = FltAttensB[ k ];
255 }
256 else
257 if( SteepIndex == 2 )
258 {
259 while( k != FltCountC - 1 && FltAttensC[ k ] < ReqAtten )
260 {
261 k++;
262 }
263
264 flt = FltPtrsC[ k ];
265 fltt = FlttBaseC + k;
266 att = FltAttensC[ k ];
267 }
268 else
269 if( SteepIndex == 3 )
270 {
271 while( k != FltCountD - 1 && FltAttensD[ k ] < ReqAtten )
272 {
273 k++;
274 }
275
276 flt = FltPtrsD[ k ];
277 fltt = FlttBaseD + k;
278 att = FltAttensD[ k ];
279 }
280 else
281 if( SteepIndex == 4 )
282 {
283 while( k != FltCountE - 1 && FltAttensE[ k ] < ReqAtten )
284 {
285 k++;
286 }
287
288 flt = FltPtrsE[ k ];
289 fltt = FlttBaseE + k;
290 att = FltAttensE[ k ];
291 }
292 else
293 if( SteepIndex == 5 )
294 {
295 while( k != FltCountF - 1 && FltAttensF[ k ] < ReqAtten )
296 {
297 k++;
298 }
299
300 flt = FltPtrsF[ k ];
301 fltt = FlttBaseF + k;
302 att = FltAttensF[ k ];
303 }
304 else
305 {
306 while( k != FltCountG - 1 && FltAttensG[ k ] < ReqAtten )
307 {
308 k++;
309 }
310
311 flt = FltPtrsG[ k ];
312 fltt = FlttBaseG + k;
313 att = FltAttensG[ k ];
314 }
315 }
316
330 static void getHBFilterThird( const double ReqAtten, const int SteepIndex,
331 const double*& flt, int& fltt, double& att )
332 {
333 static const double HBKernel_3A[ 3 ] = { // -66.3726 dB, 6
334 5.9811355069551475e-001, -1.1793396656733847e-001,
335 2.0300557211946322e-002,};
336 static const double HBKernel_4A[ 4 ] = { // -90.2546 dB, 6
337 6.0645499250612578e-001, -1.3555496505481171e-001,
338 3.4022804962365975e-002, -4.9535418595798757e-003,};
339 static const double HBKernel_5A[ 5 ] = { // -126.5507 dB, 6
340 6.1014115058940210e-001, -1.4393081816629907e-001,
341 4.1760642892852244e-002, -8.9692183234056175e-003,
342 9.9871340618342070e-004,};
343 static const double HBKernel_6A[ 6 ] = { // -150.1839 dB, 6
344 6.1439563420546972e-001, -1.5360187826905250e-001,
345 5.0840891345687034e-002, -1.4053648740561121e-002,
346 2.6771286587305727e-003, -2.5815816044823123e-004,};
347 static const double HBKernel_7A[ 7 ] = { // -173.7068 dB, 6
348 6.1747493476329918e-001, -1.6087373733313212e-001,
349 5.8263075641409430e-002, -1.8872408173431318e-002,
350 4.7421376543513687e-003, -8.0196529612267474e-004,
351 6.7964807393798996e-005,};
352 static const double HBKernel_8A[ 8 ] = { // -197.1454 dB, 6
353 6.1980610947775050e-001, -1.6654070578314714e-001,
354 6.4416567441730327e-002, -2.3307744348719822e-002,
355 6.9909157372312443e-003, -1.5871946293364403e-003,
356 2.4017727382382763e-004, -1.8125308241541697e-005,};
357 static const double HBKernel_9A[ 9 ] = { // -220.5199 dB, 6
358 6.2163188951899306e-001, -1.7108115323810941e-001,
359 6.9588370095600260e-002, -2.7339625080613838e-002,
360 9.2954469183791771e-003, -2.5537179959555429e-003,
361 5.2572290897951021e-004, -7.1813356135154921e-005,
362 4.8802382808892154e-006,};
363 static const int FltCountA = 7;
364 static const int FlttBaseA = 3;
365 static const double FltAttensA[ FltCountA ] = {
366 66.3726, 90.2546, 126.5507, 150.1839, 173.7068, 197.1454, 220.5199, };
367 static const double* const FltPtrsA[ FltCountA ] = {
368 HBKernel_3A, HBKernel_4A, HBKernel_5A, HBKernel_6A, HBKernel_7A, HBKernel_8A, HBKernel_9A, };
369 static const double HBKernel_2B[ 2 ] = { // -71.0965 dB, 12
370 5.6748544264806311e-001, -6.7764090509431732e-002,};
371 static const double HBKernel_3B[ 3 ] = { // -115.7707 dB, 12
372 5.8793612182667199e-001, -1.0070583248877293e-001,
373 1.2771337947163834e-002,};
374 static const double HBKernel_4B[ 4 ] = { // -152.1535 dB, 12
375 5.9960155600862808e-001, -1.2228154335199336e-001,
376 2.5433718917694709e-002, -2.7537562530837154e-003,};
377 static const double HBKernel_5B[ 5 ] = { // -188.2914 dB, 12
378 6.0676859170554343e-001, -1.3689667009876413e-001,
379 3.6288512631926818e-002, -6.7838855305035351e-003,
380 6.2345167677087547e-004,};
381 static const double HBKernel_6B[ 6 ] = { // -224.2705 dB, 12
382 6.1161456341904397e-001, -1.4743901958274458e-001,
383 4.5344160157313275e-002, -1.1207371780924531e-002,
384 1.8328497112594935e-003, -1.4518193006359589e-004,};
385 static const int FltCountB = 5;
386 static const int FlttBaseB = 2;
387 static const double FltAttensB[ FltCountB ] = {
388 71.0965, 115.7707, 152.1535, 188.2914, 224.2705, };
389 static const double* const FltPtrsB[ FltCountB ] = {
390 HBKernel_2B, HBKernel_3B, HBKernel_4B, HBKernel_5B, HBKernel_6B, };
391 static const double HBKernel_1C[ 1 ] = { // -49.4544 dB, 24
392 5.0336730531430562e-001,};
393 static const double HBKernel_2C[ 2 ] = { // -103.1970 dB, 24
394 5.6330232648142819e-001, -6.3309247177420452e-002,};
395 static const double HBKernel_3C[ 3 ] = { // -152.1195 dB, 24
396 5.8643891113580415e-001, -9.8411593011583087e-002,
397 1.1972706651483846e-002,};
398 static const double HBKernel_4C[ 4 ] = { // -200.6182 dB, 24
399 5.9851012363917222e-001, -1.2028885239978220e-001,
400 2.4294521083140615e-002, -2.5157924156609776e-003,};
401 static const double HBKernel_5C[ 5 ] = { // -248.8730 dB, 24
402 6.0590922882030196e-001, -1.3515953438018685e-001,
403 3.5020857107815606e-002, -6.3256196990467053e-003,
404 5.5506815147598793e-004,};
405 static const int FltCountC = 5;
406 static const int FlttBaseC = 1;
407 static const double FltAttensC[ FltCountC ] = {
408 49.4544, 103.1970, 152.1195, 200.6182, 248.8730, };
409 static const double* const FltPtrsC[ FltCountC ] = {
410 HBKernel_1C, HBKernel_2C, HBKernel_3C, HBKernel_4C, HBKernel_5C, };
411 static const double HBKernel_1D[ 1 ] = { // -61.5357 dB, 48
412 5.0083794231068057e-001,};
413 static const double HBKernel_2D[ 2 ] = { // -127.3167 dB, 48
414 5.6270074379958690e-001, -6.2701174487726344e-002,};
415 static const double HBKernel_3D[ 3 ] = { // -188.2990 dB, 48
416 5.8606296210323228e-001, -9.7844644765123029e-002,
417 1.1781683046528768e-002,};
418 static const double HBKernel_4D[ 4 ] = { // -248.8580 dB, 48
419 5.9823601243162516e-001, -1.1979368994739022e-001,
420 2.4017458606412575e-002, -2.4597810910081913e-003,};
421 static const int FltCountD = 4;
422 static const int FlttBaseD = 1;
423 static const double FltAttensD[ FltCountD ] = {
424 61.5357, 127.3167, 188.2990, 248.8580, };
425 static const double* const FltPtrsD[ FltCountD ] = {
426 HBKernel_1D, HBKernel_2D, HBKernel_3D, HBKernel_4D, };
427 static const double HBKernel_1E[ 1 ] = { // -77.4651 dB, 96
428 5.0013388897382527e-001,};
429 static const double HBKernel_2E[ 2 ] = { // -151.4084 dB, 96
430 5.6255019604317880e-001, -6.2550222932381064e-002,};
431 static const double HBKernel_3E[ 3 ] = { // -224.4365 dB, 96
432 5.8596887234201078e-001, -9.7703321113080305e-002,
433 1.1734448777069783e-002,};
434 static const int FltCountE = 3;
435 static const int FlttBaseE = 1;
436 static const double FltAttensE[ FltCountE ] = {
437 77.4651, 151.4084, 224.4365, };
438 static const double* const FltPtrsE[ FltCountE ] = {
439 HBKernel_1E, HBKernel_2E, HBKernel_3E, };
440 static const double HBKernel_1F[ 1 ] = { // -89.5075 dB, 192
441 5.0003346776264190e-001,};
442 static const double HBKernel_2F[ 2 ] = { // -175.4932 dB, 192
443 5.6251254964097952e-001, -6.2512551321105267e-002,};
444 static const double HBKernel_3F[ 3 ] = { // -260.5645 dB, 192
445 5.8594534336747051e-001, -9.7668015838639821e-002,
446 1.1722672471262996e-002,};
447 static const int FltCountF = 3;
448 static const int FlttBaseF = 1;
449 static const double FltAttensF[ FltCountF ] = {
450 89.5075, 175.4932, 260.5645, };
451 static const double* const FltPtrsF[ FltCountF ] = {
452 HBKernel_1F, HBKernel_2F, HBKernel_3F, };
453 static const double HBKernel_1G[ 1 ] = { // -101.5490 dB, 384
454 5.0000836666064941e-001,};
455 static const double HBKernel_2G[ 2 ] = { // -199.5761 dB, 384
456 5.6250313744943459e-001, -6.2503137554435345e-002,};
457 static const double HBKernel_3G[ 3 ] = { // -296.5185 dB, 384
458 5.8593945786963764e-001, -9.7659186853499613e-002,
459 1.1719728983863425e-002,};
460 static const int FltCountG = 3;
461 static const int FlttBaseG = 1;
462 static const double FltAttensG[ FltCountG ] = {
463 101.5490, 199.5761, 296.5185, };
464 static const double* const FltPtrsG[ FltCountG ] = {
465 HBKernel_1G, HBKernel_2G, HBKernel_3G, };
466
467 int k = 0;
468
469 if( SteepIndex <= 0 )
470 {
471 while( k != FltCountA - 1 && FltAttensA[ k ] < ReqAtten )
472 {
473 k++;
474 }
475
476 flt = FltPtrsA[ k ];
477 fltt = FlttBaseA + k;
478 att = FltAttensA[ k ];
479 }
480 else
481 if( SteepIndex == 1 )
482 {
483 while( k != FltCountB - 1 && FltAttensB[ k ] < ReqAtten )
484 {
485 k++;
486 }
487
488 flt = FltPtrsB[ k ];
489 fltt = FlttBaseB + k;
490 att = FltAttensB[ k ];
491 }
492 else
493 if( SteepIndex == 2 )
494 {
495 while( k != FltCountC - 1 && FltAttensC[ k ] < ReqAtten )
496 {
497 k++;
498 }
499
500 flt = FltPtrsC[ k ];
501 fltt = FlttBaseC + k;
502 att = FltAttensC[ k ];
503 }
504 else
505 if( SteepIndex == 3 )
506 {
507 while( k != FltCountD - 1 && FltAttensD[ k ] < ReqAtten )
508 {
509 k++;
510 }
511
512 flt = FltPtrsD[ k ];
513 fltt = FlttBaseD + k;
514 att = FltAttensD[ k ];
515 }
516 else
517 if( SteepIndex == 4 )
518 {
519 while( k != FltCountE - 1 && FltAttensE[ k ] < ReqAtten )
520 {
521 k++;
522 }
523
524 flt = FltPtrsE[ k ];
525 fltt = FlttBaseE + k;
526 att = FltAttensE[ k ];
527 }
528 else
529 if( SteepIndex == 5 )
530 {
531 while( k != FltCountF - 1 && FltAttensF[ k ] < ReqAtten )
532 {
533 k++;
534 }
535
536 flt = FltPtrsF[ k ];
537 fltt = FlttBaseF + k;
538 att = FltAttensF[ k ];
539 }
540 else
541 {
542 while( k != FltCountG - 1 && FltAttensG[ k ] < ReqAtten )
543 {
544 k++;
545 }
546
547 flt = FltPtrsG[ k ];
548 fltt = FlttBaseG + k;
549 att = FltAttensG[ k ];
550 }
551 }
552
571 CDSPHBUpsampler( const double ReqAtten, const int SteepIndex,
572 const bool IsThird, const double PrevLatency,
573 const bool aDoConsumeLatency = true )
574 : DoConsumeLatency( aDoConsumeLatency )
575 {
576 static const CConvolveFn FltConvFn[ 14 ] = {
577 &CDSPHBUpsampler :: convolve1, &CDSPHBUpsampler :: convolve2,
578 &CDSPHBUpsampler :: convolve3, &CDSPHBUpsampler :: convolve4,
579 &CDSPHBUpsampler :: convolve5, &CDSPHBUpsampler :: convolve6,
580 &CDSPHBUpsampler :: convolve7, &CDSPHBUpsampler :: convolve8,
581 &CDSPHBUpsampler :: convolve9, &CDSPHBUpsampler :: convolve10,
582 &CDSPHBUpsampler :: convolve11, &CDSPHBUpsampler :: convolve12,
583 &CDSPHBUpsampler :: convolve13, &CDSPHBUpsampler :: convolve14 };
584
585 const double* fltp0;
586 int fltt;
587 double att;
588
589 if( IsThird )
590 {
591 getHBFilterThird( ReqAtten, SteepIndex, fltp0, fltt, att );
592 }
593 else
594 {
595 getHBFilter( ReqAtten, SteepIndex, fltp0, fltt, att );
596 }
597
598 // Copy obtained filter to address-aligned buffer.
599
600 fltp = alignptr( FltBuf, 16 );
601 memcpy( fltp, fltp0, fltt * sizeof( fltp[ 0 ]));
602
603 convfn = FltConvFn[ fltt - 1 ];
604 fll = fltt - 1;
605 fl2 = fltt;
606 flo = fll + fl2;
607 BufRP = Buf + fll;
608
609 LatencyFrac = PrevLatency * 2.0;
610 Latency = (int) LatencyFrac;
611 LatencyFrac -= Latency;
612
613 R8BASSERT( Latency >= 0 );
614
615 if( DoConsumeLatency )
616 {
617 flb = BufLen - fll;
618 }
619 else
620 {
621 Latency += fl2 + fl2;
622 flb = BufLen - flo;
623 }
624
625 R8BCONSOLE( "CDSPHBUpsampler: sti=%i third=%i taps=%i att=%.1f "
626 "io=2/1\n", SteepIndex, (int) IsThird, fltt, att );
627
628 clear();
629 }
630
631 virtual int getInLenBeforeOutPos( const int ReqOutPos ) const
632 {
633 return( fl2 + (int) (( Latency + LatencyFrac + ReqOutPos ) * 0.5 ));
634 }
635
636 virtual int getLatency() const
637 {
638 return( DoConsumeLatency ? 0 : Latency );
639 }
640
641 virtual double getLatencyFrac() const
642 {
643 return( LatencyFrac );
644 }
645
646 virtual int getMaxOutLen( const int MaxInLen ) const
647 {
648 R8BASSERT( MaxInLen >= 0 );
649
650 return( MaxInLen * 2 );
651 }
652
653 virtual void clear()
654 {
655 if( DoConsumeLatency )
656 {
657 LatencyLeft = Latency;
658 BufLeft = 0;
659 }
660 else
661 {
662 LatencyLeft = 0;
663 BufLeft = fl2;
664 }
665
666 WritePos = 0;
667 ReadPos = flb; // Set "read" position to account for filter's latency.
668
669 memset( &Buf[ ReadPos ], 0, ( BufLen - flb ) * sizeof( Buf[ 0 ]));
670 }
671
672 virtual int process( double* ip, int l, double*& op0 )
673 {
674 R8BASSERT( l >= 0 );
675
676 double* op = op0;
677
678 while( l > 0 )
679 {
680 // Copy new input samples to the ring buffer.
681
682 const int b = min( l, min( BufLen - WritePos, flb - BufLeft ));
683
684 double* const wp1 = Buf + WritePos;
685 memcpy( wp1, ip, b * sizeof( wp1[ 0 ]));
686 const int ec = flo - WritePos;
687
688 if( ec > 0 )
689 {
690 memcpy( wp1 + BufLen, ip, min( b, ec ) * sizeof( wp1[ 0 ]));
691 }
692
693 ip += b;
694 WritePos = ( WritePos + b ) & BufLenMask;
695 l -= b;
696 BufLeft += b;
697
698 // Produce output.
699
700 const int c = BufLeft - fl2;
701
702 if( c > 0 )
703 {
704 double* const opend = op + c * 2;
705 ( *convfn )( op, opend, fltp, BufRP, ReadPos );
706
707 op = opend;
708 ReadPos = ( ReadPos + c ) & BufLenMask;
709 BufLeft -= c;
710 }
711 }
712
713 int ol = (int) ( op - op0 );
714
715 if( LatencyLeft != 0 )
716 {
717 if( LatencyLeft >= ol )
718 {
719 LatencyLeft -= ol;
720 return( 0 );
721 }
722
723 ol -= LatencyLeft;
724 op0 += LatencyLeft;
725 LatencyLeft = 0;
726 }
727
728 return( ol );
729 }
730
731private:
732 static const int BufLenBits = 9;
738 static const int BufLen = 1 << BufLenBits;
741 static const int BufLenMask = BufLen - 1;
743 double Buf[ BufLen + 27 ];
745 double FltBuf[ 14 + 2 ];
747 const double* BufRP;
748 double* fltp;
749 int fll;
750 int fl2;
751 int flo;
752 int flb;
753 double LatencyFrac;
754 int Latency;
755 int LatencyLeft;
756 int BufLeft;
758 int WritePos;
760 int ReadPos;
761 bool DoConsumeLatency;
764
765 typedef void( *CConvolveFn )( double* op, double* const opend,
766 const double* const flt, const double* const rp0, int rpos );
768 CConvolveFn convfn;
769
770#define R8BHBC1( fn ) \
771 static void fn( double* op, double* const opend, const double* const flt, \
772 const double* const rp0, int rpos ) \
773 { \
774 while( op != opend ) \
775 { \
776 const double* const rp = rp0 + rpos; \
777 op[ 0 ] = rp[ 0 ];
778
779#define R8BHBC2 \
780 rpos = ( rpos + 1 ) & BufLenMask; \
781 op += 2; \
782 } \
783 }
784
785#include "CDSPHBUpsampler.inc"
786
787#undef R8BHBC1
788#undef R8BHBC2
789};
790
791// ---------------------------------------------------------------------------
792
793} // namespace r8b
794
795#endif // R8B_CDSPHBUPSAMPLER_INCLUDED
The base virtual class for DSP processing algorithms.
#define R8BASSERT(e)
Definition: r8bconf.h:27
#define R8BCONSOLE(...)
Definition: r8bconf.h:40
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
T * alignptr(T *const ptr, const uintptr_t align)
Definition: r8bbase.h:279
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1063
Half-band upsampling class.
Definition: CDSPHBUpsampler.h:31
virtual int getMaxOutLen(const int MaxInLen) const
Definition: CDSPHBUpsampler.h:646
virtual double getLatencyFrac() const
Definition: CDSPHBUpsampler.h:641
static void getHBFilter(const double ReqAtten, const int SteepIndex, const double *&flt, int &fltt, double &att)
Definition: CDSPHBUpsampler.h:46
static void getHBFilterThird(const double ReqAtten, const int SteepIndex, const double *&flt, int &fltt, double &att)
Definition: CDSPHBUpsampler.h:330
virtual void clear()
Definition: CDSPHBUpsampler.h:653
CDSPHBUpsampler(const double ReqAtten, const int SteepIndex, const bool IsThird, const double PrevLatency, const bool aDoConsumeLatency=true)
Definition: CDSPHBUpsampler.h:571
virtual int process(double *ip, int l, double *&op0)
Definition: CDSPHBUpsampler.h:672
virtual int getInLenBeforeOutPos(const int ReqOutPos) const
Definition: CDSPHBUpsampler.h:631
virtual int getLatency() const
Definition: CDSPHBUpsampler.h:636
The base virtual class for DSP processing algorithms.
Definition: CDSPProcessor.h:32