You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

aafilter.hpp 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. // Anti-aliasing filters for common sample rates
  2. // Copyright (C) 2020 Tyler Coy
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. #pragma once
  17. #include "sos.hpp"
  18. namespace streams
  19. {
  20. /*[[[cog
  21. import math
  22. import aafilter
  23. # We design our filters to keep aliasing out of this band
  24. audio_bw = 20000
  25. # We assume the client process generates no frequency content above this
  26. # multiple of the original bandwidth
  27. max_bw_mult = 3
  28. rpass = 0.1 # Maximum passband ripple in dB
  29. rstop = 100 # Minimum stopband attenuation in dB
  30. # Generate filters for these sampling rates
  31. common_rates = [
  32. 8000,
  33. 11025, 12000,
  34. 22050, 24000,
  35. 44100, 48000,
  36. 88200, 96000,
  37. 176400, 192000,
  38. 352800, 384000,
  39. 705600, 768000
  40. ]
  41. # Oversample to at least this frequency
  42. min_oversampled_rate = audio_bw * 2 * 2
  43. up_filters = list()
  44. down_filters = list()
  45. oversampling_factors = dict()
  46. max_num_sections = 0
  47. # For each sample rate, design a pair of upsampling and downsampling filters.
  48. # For the upsampling filter, the stopband must be placed such that the client's
  49. # multiplied bandwidth won't reach into the aliased audio band. For the
  50. # downsampling filter, the stopband must be placed such that all foldover falls
  51. # above the audio band.
  52. for fs in common_rates:
  53. os = math.ceil(min_oversampled_rate / fs)
  54. oversampling_factors[fs] = os
  55. fpass = min(audio_bw, 0.475 * fs)
  56. critical_bw = fpass if fpass >= audio_bw else fs / 2
  57. up_fstop = min(fs * os / 2, (fs * os - critical_bw) / max_bw_mult)
  58. down_fstop = min(fs * os / 2, fs - critical_bw)
  59. up = aafilter.design(fs, os, fpass, up_fstop, rpass, rstop)
  60. down = aafilter.design(fs, os, fpass, down_fstop, rpass, rstop)
  61. max_num_sections = max(max_num_sections, len(up.sections), len(down.sections))
  62. up_filters.append(up)
  63. down_filters.append(down)
  64. cog.outl('static constexpr int kMaxNumSections = {};'
  65. .format(max_num_sections))
  66. ]]]*/
  67. static constexpr int kMaxNumSections = 8;
  68. //[[[end]]]
  69. inline int SampleRateID(float sample_rate)
  70. {
  71. if (false) {}
  72. /*[[[cog
  73. for fs in sorted(common_rates, reverse=True):
  74. cog.outl('else if ({} <= sample_rate) return {};'.format(fs, fs))
  75. cog.outl('else return {};'.format(min(common_rates)))
  76. ]]]*/
  77. else if (768000 <= sample_rate) return 768000;
  78. else if (705600 <= sample_rate) return 705600;
  79. else if (384000 <= sample_rate) return 384000;
  80. else if (352800 <= sample_rate) return 352800;
  81. else if (192000 <= sample_rate) return 192000;
  82. else if (176400 <= sample_rate) return 176400;
  83. else if (96000 <= sample_rate) return 96000;
  84. else if (88200 <= sample_rate) return 88200;
  85. else if (48000 <= sample_rate) return 48000;
  86. else if (44100 <= sample_rate) return 44100;
  87. else if (24000 <= sample_rate) return 24000;
  88. else if (22050 <= sample_rate) return 22050;
  89. else if (12000 <= sample_rate) return 12000;
  90. else if (11025 <= sample_rate) return 11025;
  91. else if (8000 <= sample_rate) return 8000;
  92. else return 8000;
  93. //[[[end]]]
  94. }
  95. inline int OversamplingFactor(float sample_rate)
  96. {
  97. switch (SampleRateID(sample_rate))
  98. {
  99. default:
  100. /*[[[cog
  101. for fs in sorted(common_rates):
  102. cog.outl('case {}: return {};'.format(fs, oversampling_factors[fs]))
  103. ]]]*/
  104. case 8000: return 10;
  105. case 11025: return 8;
  106. case 12000: return 7;
  107. case 22050: return 4;
  108. case 24000: return 4;
  109. case 44100: return 2;
  110. case 48000: return 2;
  111. case 88200: return 1;
  112. case 96000: return 1;
  113. case 176400: return 1;
  114. case 192000: return 1;
  115. case 352800: return 1;
  116. case 384000: return 1;
  117. case 705600: return 1;
  118. case 768000: return 1;
  119. //[[[end]]]
  120. }
  121. }
  122. template <typename T>
  123. class AAFilter
  124. {
  125. public:
  126. void Init(float sample_rate)
  127. {
  128. InitFilter(sample_rate);
  129. }
  130. T Process(T in)
  131. {
  132. return filter_.Process(in);
  133. }
  134. protected:
  135. SOSFilter<T, kMaxNumSections> filter_;
  136. virtual void InitFilter(float sample_rate) = 0;
  137. };
  138. template <typename T>
  139. class UpsamplingAAFilter : public AAFilter<T>
  140. {
  141. void InitFilter(float sample_rate) override
  142. {
  143. switch (SampleRateID(sample_rate))
  144. {
  145. default:
  146. /*[[[cog
  147. aafilter.print_filter_cases(up_filters)
  148. ]]]*/
  149. case 8000: // o = 10, fp = 3799, fst = 25333, cost = 160000
  150. {
  151. const SOSCoefficients kFilter8000x10[2] =
  152. {
  153. { {4.63786610e-04, 8.16220909e-04, 4.63786610e-04, }, {-1.63450649e+00, 6.81471340e-01, } },
  154. { {1.00000000e+00, 9.17818354e-01, 1.00000000e+00, }, {-1.74936370e+00, 8.57701633e-01, } },
  155. };
  156. AAFilter<T>::filter_.Init(2, kFilter8000x10);
  157. break;
  158. }
  159. case 11025: // o = 8, fp = 5236, fst = 27562, cost = 264600
  160. {
  161. const SOSCoefficients kFilter11025x8[3] =
  162. {
  163. { {8.58405971e-05, 1.10355095e-04, 8.58405971e-05, }, {-1.68369279e+00, 7.17693063e-01, } },
  164. { {1.00000000e+00, -4.51272752e-01, 1.00000000e+00, }, {-1.70761645e+00, 7.97046177e-01, } },
  165. { {1.00000000e+00, -9.69385103e-01, 1.00000000e+00, }, {-1.77709771e+00, 9.25148961e-01, } },
  166. };
  167. AAFilter<T>::filter_.Init(3, kFilter11025x8);
  168. break;
  169. }
  170. case 12000: // o = 7, fp = 5700, fst = 26000, cost = 252000
  171. {
  172. const SOSCoefficients kFilter12000x7[3] =
  173. {
  174. { {1.23289409e-04, 1.76631634e-04, 1.23289409e-04, }, {-1.63990095e+00, 6.83607830e-01, } },
  175. { {1.00000000e+00, -1.84350251e-01, 1.00000000e+00, }, {-1.65709238e+00, 7.72217183e-01, } },
  176. { {1.00000000e+00, -7.46080513e-01, 1.00000000e+00, }, {-1.72410914e+00, 9.15596208e-01, } },
  177. };
  178. AAFilter<T>::filter_.Init(3, kFilter12000x7);
  179. break;
  180. }
  181. case 22050: // o = 4, fp = 10473, fst = 25725, cost = 264600
  182. {
  183. const SOSCoefficients kFilter22050x4[3] =
  184. {
  185. { {8.28104239e-04, 1.49680255e-03, 8.28104239e-04, }, {-1.37972564e+00, 5.03689463e-01, } },
  186. { {1.00000000e+00, 9.23962985e-01, 1.00000000e+00, }, {-1.31894849e+00, 6.44142088e-01, } },
  187. { {1.00000000e+00, 3.95355727e-01, 1.00000000e+00, }, {-1.31864199e+00, 8.66452582e-01, } },
  188. };
  189. AAFilter<T>::filter_.Init(3, kFilter22050x4);
  190. break;
  191. }
  192. case 24000: // o = 4, fp = 11400, fst = 28000, cost = 288000
  193. {
  194. const SOSCoefficients kFilter24000x4[3] =
  195. {
  196. { {8.28104239e-04, 1.49680255e-03, 8.28104239e-04, }, {-1.37972564e+00, 5.03689463e-01, } },
  197. { {1.00000000e+00, 9.23962985e-01, 1.00000000e+00, }, {-1.31894849e+00, 6.44142088e-01, } },
  198. { {1.00000000e+00, 3.95355727e-01, 1.00000000e+00, }, {-1.31864199e+00, 8.66452582e-01, } },
  199. };
  200. AAFilter<T>::filter_.Init(3, kFilter24000x4);
  201. break;
  202. }
  203. case 44100: // o = 2, fp = 20000, fst = 22733, cost = 529200
  204. {
  205. const SOSCoefficients kFilter44100x2[6] =
  206. {
  207. { {1.79111485e-03, 3.36261548e-03, 1.79111485e-03, }, {-1.13743427e+00, 3.66260569e-01, } },
  208. { {1.00000000e+00, 1.20719512e+00, 1.00000000e+00, }, {-9.11565008e-01, 5.12543165e-01, } },
  209. { {1.00000000e+00, 6.02914008e-01, 1.00000000e+00, }, {-6.39374195e-01, 6.90602186e-01, } },
  210. { {1.00000000e+00, 2.52534955e-01, 1.00000000e+00, }, {-4.37984152e-01, 8.26937992e-01, } },
  211. { {1.00000000e+00, 7.75467885e-02, 1.00000000e+00, }, {-3.22061575e-01, 9.15513587e-01, } },
  212. { {1.00000000e+00, 6.28451771e-03, 1.00000000e+00, }, {-2.73474858e-01, 9.74748983e-01, } },
  213. };
  214. AAFilter<T>::filter_.Init(6, kFilter44100x2);
  215. break;
  216. }
  217. case 48000: // o = 2, fp = 20000, fst = 25333, cost = 480000
  218. {
  219. const SOSCoefficients kFilter48000x2[5] =
  220. {
  221. { {1.56483717e-03, 2.92030174e-03, 1.56483717e-03, }, {-1.17455774e+00, 3.85298764e-01, } },
  222. { {1.00000000e+00, 1.15074177e+00, 1.00000000e+00, }, {-9.70672689e-01, 5.26603999e-01, } },
  223. { {1.00000000e+00, 5.31582897e-01, 1.00000000e+00, }, {-7.26313285e-01, 7.02981269e-01, } },
  224. { {1.00000000e+00, 1.94109007e-01, 1.00000000e+00, }, {-5.54517652e-01, 8.45646275e-01, } },
  225. { {1.00000000e+00, 5.47965468e-02, 1.00000000e+00, }, {-4.79572665e-01, 9.52220684e-01, } },
  226. };
  227. AAFilter<T>::filter_.Init(5, kFilter48000x2);
  228. break;
  229. }
  230. case 88200: // o = 1, fp = 20000, fst = 22733, cost = 529200
  231. {
  232. const SOSCoefficients kFilter88200x1[6] =
  233. {
  234. { {1.79111485e-03, 3.36261548e-03, 1.79111485e-03, }, {-1.13743427e+00, 3.66260569e-01, } },
  235. { {1.00000000e+00, 1.20719512e+00, 1.00000000e+00, }, {-9.11565008e-01, 5.12543165e-01, } },
  236. { {1.00000000e+00, 6.02914008e-01, 1.00000000e+00, }, {-6.39374195e-01, 6.90602186e-01, } },
  237. { {1.00000000e+00, 2.52534955e-01, 1.00000000e+00, }, {-4.37984152e-01, 8.26937992e-01, } },
  238. { {1.00000000e+00, 7.75467885e-02, 1.00000000e+00, }, {-3.22061575e-01, 9.15513587e-01, } },
  239. { {1.00000000e+00, 6.28451771e-03, 1.00000000e+00, }, {-2.73474858e-01, 9.74748983e-01, } },
  240. };
  241. AAFilter<T>::filter_.Init(6, kFilter88200x1);
  242. break;
  243. }
  244. case 96000: // o = 1, fp = 20000, fst = 25333, cost = 480000
  245. {
  246. const SOSCoefficients kFilter96000x1[5] =
  247. {
  248. { {1.56483717e-03, 2.92030174e-03, 1.56483717e-03, }, {-1.17455774e+00, 3.85298764e-01, } },
  249. { {1.00000000e+00, 1.15074177e+00, 1.00000000e+00, }, {-9.70672689e-01, 5.26603999e-01, } },
  250. { {1.00000000e+00, 5.31582897e-01, 1.00000000e+00, }, {-7.26313285e-01, 7.02981269e-01, } },
  251. { {1.00000000e+00, 1.94109007e-01, 1.00000000e+00, }, {-5.54517652e-01, 8.45646275e-01, } },
  252. { {1.00000000e+00, 5.47965468e-02, 1.00000000e+00, }, {-4.79572665e-01, 9.52220684e-01, } },
  253. };
  254. AAFilter<T>::filter_.Init(5, kFilter96000x1);
  255. break;
  256. }
  257. case 176400: // o = 1, fp = 20000, fst = 52133, cost = 529200
  258. {
  259. const SOSCoefficients kFilter176400x1[3] =
  260. {
  261. { {6.91751141e-04, 1.23689749e-03, 6.91751141e-04, }, {-1.40714871e+00, 5.20902227e-01, } },
  262. { {1.00000000e+00, 8.42431018e-01, 1.00000000e+00, }, {-1.35717505e+00, 6.56002263e-01, } },
  263. { {1.00000000e+00, 2.97097489e-01, 1.00000000e+00, }, {-1.36759134e+00, 8.70920336e-01, } },
  264. };
  265. AAFilter<T>::filter_.Init(3, kFilter176400x1);
  266. break;
  267. }
  268. case 192000: // o = 1, fp = 20000, fst = 57333, cost = 576000
  269. {
  270. const SOSCoefficients kFilter192000x1[3] =
  271. {
  272. { {5.02504803e-04, 8.78421990e-04, 5.02504803e-04, }, {-1.45413648e+00, 5.51330003e-01, } },
  273. { {1.00000000e+00, 6.85942380e-01, 1.00000000e+00, }, {-1.42143582e+00, 6.77242054e-01, } },
  274. { {1.00000000e+00, 1.15756990e-01, 1.00000000e+00, }, {-1.44850505e+00, 8.78995879e-01, } },
  275. };
  276. AAFilter<T>::filter_.Init(3, kFilter192000x1);
  277. break;
  278. }
  279. case 352800: // o = 1, fp = 20000, fst = 110933, cost = 1058400
  280. {
  281. const SOSCoefficients kFilter352800x1[3] =
  282. {
  283. { {7.63562466e-05, 9.37911276e-05, 7.63562466e-05, }, {-1.69760825e+00, 7.28764991e-01, } },
  284. { {1.00000000e+00, -5.40096033e-01, 1.00000000e+00, }, {-1.72321786e+00, 8.05120281e-01, } },
  285. { {1.00000000e+00, -1.04012920e+00, 1.00000000e+00, }, {-1.79287839e+00, 9.28245030e-01, } },
  286. };
  287. AAFilter<T>::filter_.Init(3, kFilter352800x1);
  288. break;
  289. }
  290. case 384000: // o = 1, fp = 20000, fst = 121333, cost = 1152000
  291. {
  292. const SOSCoefficients kFilter384000x1[3] =
  293. {
  294. { {6.23104401e-05, 6.94740629e-05, 6.23104401e-05, }, {-1.72153665e+00, 7.48079159e-01, } },
  295. { {1.00000000e+00, -6.96283878e-01, 1.00000000e+00, }, {-1.74951535e+00, 8.19207305e-01, } },
  296. { {1.00000000e+00, -1.16050137e+00, 1.00000000e+00, }, {-1.81879173e+00, 9.33631596e-01, } },
  297. };
  298. AAFilter<T>::filter_.Init(3, kFilter384000x1);
  299. break;
  300. }
  301. case 705600: // o = 1, fp = 20000, fst = 228533, cost = 1411200
  302. {
  303. const SOSCoefficients kFilter705600x1[2] =
  304. {
  305. { {1.08339911e-04, 1.50243615e-04, 1.08339911e-04, }, {-1.77824462e+00, 7.96098482e-01, } },
  306. { {1.00000000e+00, -5.03405956e-02, 1.00000000e+00, }, {-1.87131112e+00, 9.11379528e-01, } },
  307. };
  308. AAFilter<T>::filter_.Init(2, kFilter705600x1);
  309. break;
  310. }
  311. case 768000: // o = 1, fp = 20000, fst = 249333, cost = 1536000
  312. {
  313. const SOSCoefficients kFilter768000x1[2] =
  314. {
  315. { {8.80491172e-05, 1.13851506e-04, 8.80491172e-05, }, {-1.79584317e+00, 8.11038264e-01, } },
  316. { {1.00000000e+00, -2.19769620e-01, 1.00000000e+00, }, {-1.88421935e+00, 9.18189356e-01, } },
  317. };
  318. AAFilter<T>::filter_.Init(2, kFilter768000x1);
  319. break;
  320. }
  321. //[[[end]]]
  322. }
  323. }
  324. };
  325. template <typename T>
  326. class DownsamplingAAFilter : public AAFilter<T>
  327. {
  328. void InitFilter(float sample_rate) override
  329. {
  330. switch (SampleRateID(sample_rate))
  331. {
  332. default:
  333. /*[[[cog
  334. aafilter.print_filter_cases(down_filters)
  335. ]]]*/
  336. case 8000: // o = 10, fp = 3799, fst = 4000, cost = 640000
  337. {
  338. const SOSCoefficients kFilter8000x10[8] =
  339. {
  340. { {1.74724987e-05, -2.65793181e-06, 1.74724987e-05, }, {-1.83684224e+00, 8.46022748e-01, } },
  341. { {1.00000000e+00, -1.60455772e+00, 1.00000000e+00, }, {-1.85073181e+00, 8.75957566e-01, } },
  342. { {1.00000000e+00, -1.80816772e+00, 1.00000000e+00, }, {-1.86939499e+00, 9.16147406e-01, } },
  343. { {1.00000000e+00, -1.86608225e+00, 1.00000000e+00, }, {-1.88504252e+00, 9.49754529e-01, } },
  344. { {1.00000000e+00, -1.88843627e+00, 1.00000000e+00, }, {-1.89555097e+00, 9.72128817e-01, } },
  345. { {1.00000000e+00, -1.89828300e+00, 1.00000000e+00, }, {-1.90199243e+00, 9.85446639e-01, } },
  346. { {1.00000000e+00, -1.90275515e+00, 1.00000000e+00, }, {-1.90608719e+00, 9.93153182e-01, } },
  347. { {1.00000000e+00, -1.90451538e+00, 1.00000000e+00, }, {-1.90935079e+00, 9.98002792e-01, } },
  348. };
  349. AAFilter<T>::filter_.Init(8, kFilter8000x10);
  350. break;
  351. }
  352. case 11025: // o = 8, fp = 5236, fst = 5512, cost = 705600
  353. {
  354. const SOSCoefficients kFilter11025x8[8] =
  355. {
  356. { {2.28458309e-05, 6.85495861e-06, 2.28458309e-05, }, {-1.79651426e+00, 8.10683491e-01, } },
  357. { {1.00000000e+00, -1.41042952e+00, 1.00000000e+00, }, {-1.80827124e+00, 8.47262510e-01, } },
  358. { {1.00000000e+00, -1.70583736e+00, 1.00000000e+00, }, {-1.82413424e+00, 8.96543400e-01, } },
  359. { {1.00000000e+00, -1.79296606e+00, 1.00000000e+00, }, {-1.83751071e+00, 9.37903530e-01, } },
  360. { {1.00000000e+00, -1.82697868e+00, 1.00000000e+00, }, {-1.84658043e+00, 9.65516086e-01, } },
  361. { {1.00000000e+00, -1.84202935e+00, 1.00000000e+00, }, {-1.85227474e+00, 9.81981088e-01, } },
  362. { {1.00000000e+00, -1.84887890e+00, 1.00000000e+00, }, {-1.85613708e+00, 9.91518889e-01, } },
  363. { {1.00000000e+00, -1.85157727e+00, 1.00000000e+00, }, {-1.85962400e+00, 9.97525116e-01, } },
  364. };
  365. AAFilter<T>::filter_.Init(8, kFilter11025x8);
  366. break;
  367. }
  368. case 12000: // o = 7, fp = 5700, fst = 6000, cost = 672000
  369. {
  370. const SOSCoefficients kFilter12000x7[8] =
  371. {
  372. { {2.79174308e-05, 1.56664250e-05, 2.79174308e-05, }, {-1.76770492e+00, 7.86069996e-01, } },
  373. { {1.00000000e+00, -1.25883414e+00, 1.00000000e+00, }, {-1.77670663e+00, 8.27280516e-01, } },
  374. { {1.00000000e+00, -1.62177587e+00, 1.00000000e+00, }, {-1.78888474e+00, 8.82894847e-01, } },
  375. { {1.00000000e+00, -1.73200235e+00, 1.00000000e+00, }, {-1.79920477e+00, 9.29653670e-01, } },
  376. { {1.00000000e+00, -1.77543744e+00, 1.00000000e+00, }, {-1.80628315e+00, 9.60912839e-01, } },
  377. { {1.00000000e+00, -1.79473107e+00, 1.00000000e+00, }, {-1.81087559e+00, 9.79568474e-01, } },
  378. { {1.00000000e+00, -1.80352658e+00, 1.00000000e+00, }, {-1.81426259e+00, 9.90380916e-01, } },
  379. { {1.00000000e+00, -1.80699414e+00, 1.00000000e+00, }, {-1.81775362e+00, 9.97192369e-01, } },
  380. };
  381. AAFilter<T>::filter_.Init(8, kFilter12000x7);
  382. break;
  383. }
  384. case 22050: // o = 4, fp = 10473, fst = 11025, cost = 705600
  385. {
  386. const SOSCoefficients kFilter22050x4[8] =
  387. {
  388. { {9.74314780e-05, 1.37711747e-04, 9.74314780e-05, }, {-1.59261637e+00, 6.47353056e-01, } },
  389. { {1.00000000e+00, -2.94219878e-01, 1.00000000e+00, }, {-1.56519364e+00, 7.15705529e-01, } },
  390. { {1.00000000e+00, -9.81960881e-01, 1.00000000e+00, }, {-1.52839642e+00, 8.07626243e-01, } },
  391. { {1.00000000e+00, -1.23949615e+00, 1.00000000e+00, }, {-1.49778996e+00, 8.84625474e-01, } },
  392. { {1.00000000e+00, -1.34882542e+00, 1.00000000e+00, }, {-1.47786684e+00, 9.35956597e-01, } },
  393. { {1.00000000e+00, -1.39893677e+00, 1.00000000e+00, }, {-1.46698417e+00, 9.66536770e-01, } },
  394. { {1.00000000e+00, -1.42210887e+00, 1.00000000e+00, }, {-1.46262788e+00, 9.84243409e-01, } },
  395. { {1.00000000e+00, -1.43130155e+00, 1.00000000e+00, }, {-1.46352911e+00, 9.95397324e-01, } },
  396. };
  397. AAFilter<T>::filter_.Init(8, kFilter22050x4);
  398. break;
  399. }
  400. case 24000: // o = 4, fp = 11400, fst = 12000, cost = 768000
  401. {
  402. const SOSCoefficients kFilter24000x4[8] =
  403. {
  404. { {9.74314780e-05, 1.37711747e-04, 9.74314780e-05, }, {-1.59261637e+00, 6.47353056e-01, } },
  405. { {1.00000000e+00, -2.94219878e-01, 1.00000000e+00, }, {-1.56519364e+00, 7.15705529e-01, } },
  406. { {1.00000000e+00, -9.81960881e-01, 1.00000000e+00, }, {-1.52839642e+00, 8.07626243e-01, } },
  407. { {1.00000000e+00, -1.23949615e+00, 1.00000000e+00, }, {-1.49778996e+00, 8.84625474e-01, } },
  408. { {1.00000000e+00, -1.34882542e+00, 1.00000000e+00, }, {-1.47786684e+00, 9.35956597e-01, } },
  409. { {1.00000000e+00, -1.39893677e+00, 1.00000000e+00, }, {-1.46698417e+00, 9.66536770e-01, } },
  410. { {1.00000000e+00, -1.42210887e+00, 1.00000000e+00, }, {-1.46262788e+00, 9.84243409e-01, } },
  411. { {1.00000000e+00, -1.43130155e+00, 1.00000000e+00, }, {-1.46352911e+00, 9.95397324e-01, } },
  412. };
  413. AAFilter<T>::filter_.Init(8, kFilter24000x4);
  414. break;
  415. }
  416. case 44100: // o = 2, fp = 20000, fst = 24100, cost = 441000
  417. {
  418. const SOSCoefficients kFilter44100x2[5] =
  419. {
  420. { {2.47147477e-03, 4.68008071e-03, 2.47147477e-03, }, {-1.08909166e+00, 3.42723010e-01, } },
  421. { {1.00000000e+00, 1.29826448e+00, 1.00000000e+00, }, {-8.40340328e-01, 5.00534399e-01, } },
  422. { {1.00000000e+00, 7.43776254e-01, 1.00000000e+00, }, {-5.49893538e-01, 6.91539899e-01, } },
  423. { {1.00000000e+00, 4.24723977e-01, 1.00000000e+00, }, {-3.48795082e-01, 8.41459476e-01, } },
  424. { {1.00000000e+00, 2.89331378e-01, 1.00000000e+00, }, {-2.57028674e-01, 9.51166241e-01, } },
  425. };
  426. AAFilter<T>::filter_.Init(5, kFilter44100x2);
  427. break;
  428. }
  429. case 48000: // o = 2, fp = 20000, fst = 28000, cost = 480000
  430. {
  431. const SOSCoefficients kFilter48000x2[5] =
  432. {
  433. { {1.56483717e-03, 2.92030174e-03, 1.56483717e-03, }, {-1.17455774e+00, 3.85298764e-01, } },
  434. { {1.00000000e+00, 1.15074177e+00, 1.00000000e+00, }, {-9.70672689e-01, 5.26603999e-01, } },
  435. { {1.00000000e+00, 5.31582897e-01, 1.00000000e+00, }, {-7.26313285e-01, 7.02981269e-01, } },
  436. { {1.00000000e+00, 1.94109007e-01, 1.00000000e+00, }, {-5.54517652e-01, 8.45646275e-01, } },
  437. { {1.00000000e+00, 5.47965468e-02, 1.00000000e+00, }, {-4.79572665e-01, 9.52220684e-01, } },
  438. };
  439. AAFilter<T>::filter_.Init(5, kFilter48000x2);
  440. break;
  441. }
  442. case 88200: // o = 1, fp = 20000, fst = 44100, cost = 88200
  443. {
  444. const SOSCoefficients kFilter88200x1[1] =
  445. {
  446. { {4.47760494e-01, 8.95513661e-01, 4.47760494e-01, }, {5.33267789e-01, 2.57766861e-01, } },
  447. };
  448. AAFilter<T>::filter_.Init(1, kFilter88200x1);
  449. break;
  450. }
  451. case 96000: // o = 1, fp = 20000, fst = 48000, cost = 96000
  452. {
  453. const SOSCoefficients kFilter96000x1[1] =
  454. {
  455. { {4.08937060e-01, 8.17865642e-01, 4.08937060e-01, }, {3.98731881e-01, 2.37007882e-01, } },
  456. };
  457. AAFilter<T>::filter_.Init(1, kFilter96000x1);
  458. break;
  459. }
  460. case 176400: // o = 1, fp = 20000, fst = 88200, cost = 176400
  461. {
  462. const SOSCoefficients kFilter176400x1[1] =
  463. {
  464. { {1.95938020e-01, 3.91858763e-01, 1.95938020e-01, }, {-4.62313019e-01, 2.46047822e-01, } },
  465. };
  466. AAFilter<T>::filter_.Init(1, kFilter176400x1);
  467. break;
  468. }
  469. case 192000: // o = 1, fp = 20000, fst = 96000, cost = 192000
  470. {
  471. const SOSCoefficients kFilter192000x1[1] =
  472. {
  473. { {1.74603587e-01, 3.49188678e-01, 1.74603587e-01, }, {-5.65216145e-01, 2.63611998e-01, } },
  474. };
  475. AAFilter<T>::filter_.Init(1, kFilter192000x1);
  476. break;
  477. }
  478. case 352800: // o = 1, fp = 20000, fst = 176400, cost = 352800
  479. {
  480. const SOSCoefficients kFilter352800x1[1] =
  481. {
  482. { {6.99874107e-02, 1.39948456e-01, 6.99874107e-02, }, {-1.16347041e+00, 4.43393682e-01, } },
  483. };
  484. AAFilter<T>::filter_.Init(1, kFilter352800x1);
  485. break;
  486. }
  487. case 384000: // o = 1, fp = 20000, fst = 192000, cost = 384000
  488. {
  489. const SOSCoefficients kFilter384000x1[1] =
  490. {
  491. { {6.09620331e-02, 1.21896769e-01, 6.09620331e-02, }, {-1.22760212e+00, 4.71422957e-01, } },
  492. };
  493. AAFilter<T>::filter_.Init(1, kFilter384000x1);
  494. break;
  495. }
  496. case 705600: // o = 1, fp = 20000, fst = 352800, cost = 705600
  497. {
  498. const SOSCoefficients kFilter705600x1[1] =
  499. {
  500. { {2.13438638e-02, 4.26550556e-02, 2.13438638e-02, }, {-1.57253460e+00, 6.57877382e-01, } },
  501. };
  502. AAFilter<T>::filter_.Init(1, kFilter705600x1);
  503. break;
  504. }
  505. case 768000: // o = 1, fp = 20000, fst = 384000, cost = 768000
  506. {
  507. const SOSCoefficients kFilter768000x1[1] =
  508. {
  509. { {1.83197956e-02, 3.66063440e-02, 1.83197956e-02, }, {-1.60702602e+00, 6.80271956e-01, } },
  510. };
  511. AAFilter<T>::filter_.Init(1, kFilter768000x1);
  512. break;
  513. }
  514. //[[[end]]]
  515. }
  516. }
  517. };
  518. }