2015-07-08 11:39:24 -04:00
/*
* Copyright ( C ) 2015 Jared Boone , ShareBrained Technology , Inc .
2017-11-28 02:52:04 -05:00
* Copyright ( C ) 2017 Furrtek
2015-07-08 11:39:24 -04:00
*
* This file is part of PortaPack .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; see the file COPYING . If not , write to
* the Free Software Foundation , Inc . , 51 Franklin Street ,
* Boston , MA 02110 - 1301 , USA .
*/
# ifndef __DSP_FIR_TAPS_H__
# define __DSP_FIR_TAPS_H__
# include <cstdint>
# include <array>
# include "complex.hpp"
2023-05-18 16:16:05 -04:00
template < size_t N >
2015-07-18 14:35:31 -04:00
struct fir_taps_real {
2023-05-18 16:16:05 -04:00
float low_frequency_normalized ;
float high_frequency_normalized ;
float transition_normalized ;
std : : array < int16_t , N > taps ;
2015-07-18 14:35:31 -04:00
} ;
2023-05-18 16:16:05 -04:00
template < size_t N >
2016-01-30 01:29:23 -05:00
struct fir_taps_complex {
2023-05-18 16:16:05 -04:00
float low_frequency_normalized ;
float high_frequency_normalized ;
float transition_normalized ;
std : : array < complex16_t , N > taps ;
2016-01-30 01:29:23 -05:00
} ;
2015-12-30 15:19:42 -05:00
// NBFM 16K0F3E emission type /////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=8000, stop=344000, decim=8, fout=384000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 24 > taps_16k0_decim_0 {
. low_frequency_normalized = - 8000.0f / 3072000.0f ,
. high_frequency_normalized = 8000.0f / 3072000.0f ,
. transition_normalized = 336000.0f / 3072000.0f ,
. taps = { {
1 ,
67 ,
165 ,
340 ,
599 ,
944 ,
1361 ,
1820 ,
2278 ,
2684 ,
2988 ,
3152 ,
3152 ,
2988 ,
2684 ,
2278 ,
1820 ,
1361 ,
944 ,
599 ,
340 ,
165 ,
67 ,
1 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// IFIR prototype filter: fs=384000, pass=8000, stop=40000, decim=8, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_16k0_decim_1 {
. low_frequency_normalized = - 8000.0f / 384000.0f ,
. high_frequency_normalized = 8000.0f / 384000.0f ,
. transition_normalized = 32000.0f / 384000.0f ,
. taps = { {
- 26 ,
- 125 ,
- 180 ,
- 275 ,
- 342 ,
- 359 ,
- 286 ,
- 90 ,
250 ,
733 ,
1337 ,
2011 ,
2688 ,
3289 ,
3740 ,
3982 ,
3982 ,
3740 ,
3289 ,
2688 ,
2011 ,
1337 ,
733 ,
250 ,
- 90 ,
- 286 ,
- 359 ,
- 342 ,
- 275 ,
- 180 ,
- 125 ,
- 26 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// Channel filter: fs=48000, pass=8000, stop=12400, decim=1, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_16k0_channel {
. low_frequency_normalized = - 8000.0f / 48000.0f ,
. high_frequency_normalized = 8000.0f / 48000.0f ,
. transition_normalized = 4400.0f / 48000.0f ,
. taps = { {
- 73 ,
- 285 ,
- 376 ,
- 8 ,
609 ,
538 ,
- 584 ,
- 1387 ,
- 148 ,
2173 ,
1959 ,
- 2146 ,
- 5267 ,
- 297 ,
12915 ,
24737 ,
24737 ,
12915 ,
- 297 ,
- 5267 ,
- 2146 ,
1959 ,
2173 ,
- 148 ,
- 1387 ,
- 584 ,
538 ,
609 ,
- 8 ,
- 376 ,
- 285 ,
- 73 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// NBFM 11K0F3E emission type /////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=5500, stop=341500, decim=8, fout=384000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 24 > taps_11k0_decim_0 {
. low_frequency_normalized = - 5500.0f / 3072000.0f ,
. high_frequency_normalized = 5500.0f / 3072000.0f ,
. transition_normalized = 336000.0f / 3072000.0f ,
. taps = { {
38 ,
102 ,
220 ,
406 ,
668 ,
1004 ,
1397 ,
1822 ,
2238 ,
2603 ,
2875 ,
3020 ,
3020 ,
2875 ,
2603 ,
2238 ,
1822 ,
1397 ,
1004 ,
668 ,
406 ,
220 ,
102 ,
38 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// IFIR prototype filter: fs=384000, pass=5500, stop=42500, decim=8, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_11k0_decim_1 {
. low_frequency_normalized = - 5500.0f / 384000.0f ,
. high_frequency_normalized = 5500.0f / 384000.0f ,
. transition_normalized = 37000.0f / 384000.0f ,
. taps = { {
- 42 ,
- 87 ,
- 157 ,
- 234 ,
- 298 ,
- 318 ,
- 255 ,
- 75 ,
246 ,
713 ,
1306 ,
1976 ,
2656 ,
3265 ,
3724 ,
3971 ,
3971 ,
3724 ,
3265 ,
2656 ,
1976 ,
1306 ,
713 ,
246 ,
- 75 ,
- 255 ,
- 318 ,
- 298 ,
- 234 ,
- 157 ,
- 87 ,
- 42 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// Channel filter: fs=48000, pass=5500, stop=8900, decim=1, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_11k0_channel {
. low_frequency_normalized = - 5500.0f / 48000.0f ,
. high_frequency_normalized = 5500.0f / 48000.0f ,
. transition_normalized = 3400.0f / 48000.0f ,
. taps = { {
- 68 ,
- 345 ,
- 675 ,
- 867 ,
- 582 ,
247 ,
1222 ,
1562 ,
634 ,
- 1379 ,
- 3219 ,
- 3068 ,
310 ,
6510 ,
13331 ,
17795 ,
17795 ,
13331 ,
6510 ,
310 ,
- 3068 ,
- 3219 ,
- 1379 ,
634 ,
1562 ,
1222 ,
247 ,
- 582 ,
- 867 ,
- 675 ,
- 345 ,
- 68 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2017-11-28 02:52:04 -05:00
// NBFM 8K50F3E emission type /////////////////////////////////////////////
2015-12-30 15:19:42 -05:00
// IFIR image-reject filter: fs=3072000, pass=4250, stop=340250, decim=8, fout=384000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 24 > taps_4k25_decim_0 {
. low_frequency_normalized = - 4250.0f / 3072000.0f ,
. high_frequency_normalized = 4250.0f / 3072000.0f ,
. transition_normalized = 33600.0f / 3072000.0f ,
. taps = { {
38 ,
103 ,
222 ,
409 ,
671 ,
1006 ,
1399 ,
1821 ,
2236 ,
2599 ,
2868 ,
3012 ,
3012 ,
2868 ,
2599 ,
2236 ,
1821 ,
1399 ,
1006 ,
671 ,
409 ,
222 ,
103 ,
38 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// IFIR prototype filter: fs=384000, pass=4250, stop=43750, decim=8, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_4k25_decim_1 {
. low_frequency_normalized = - 4250.0f / 384000.0f ,
. high_frequency_normalized = 4250.0f / 384000.0f ,
. transition_normalized = 39500.0f / 384000.0f ,
. taps = { {
- 33 ,
- 74 ,
- 139 ,
- 214 ,
- 280 ,
- 306 ,
- 254 ,
- 87 ,
222 ,
682 ,
1274 ,
1951 ,
2644 ,
3268 ,
3741 ,
3996 ,
3996 ,
3741 ,
3268 ,
2644 ,
1951 ,
1274 ,
682 ,
222 ,
- 87 ,
- 254 ,
- 306 ,
- 280 ,
- 214 ,
- 139 ,
- 74 ,
- 33 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2015-12-30 15:19:42 -05:00
// Channel filter: fs=48000, pass=4250, stop=7900, decim=1, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_4k25_channel {
. low_frequency_normalized = - 4250.0f / 48000.0f ,
. high_frequency_normalized = 4250.0f / 48000.0f ,
. transition_normalized = 3650.0f / 48000.0f ,
. taps = { {
- 58 ,
- 14 ,
153 ,
484 ,
871 ,
1063 ,
770 ,
- 141 ,
- 1440 ,
- 2488 ,
- 2435 ,
- 614 ,
3035 ,
7771 ,
12226 ,
14927 ,
14927 ,
12226 ,
7771 ,
3035 ,
- 614 ,
- 2435 ,
- 2488 ,
- 1440 ,
- 141 ,
770 ,
1063 ,
871 ,
484 ,
153 ,
- 14 ,
- 58 ,
} } ,
2015-12-30 15:19:42 -05:00
} ;
2017-11-28 02:52:04 -05:00
/* CTCSS audio filter */
/* 12kHz int16_t input
* - > FIR filter , < 300 Hz pass , > 300 Hz stop , gain of 1
* - > 6 kHz int16_t output , gain of 1.0 ( I think ) .
* Padded to multiple of four taps for unrolled FIR code .
* sum ( abs ( taps ) ) : 125270
*/
/*constexpr fir_taps_real<64> taps_64_lp_025_025 {
2023-05-18 16:16:05 -04:00
. taps = { {
0 , 0 , - 3 , - 7 , - 13 , - 20 , - 27 , - 32 ,
- 34 , - 33 , - 25 , - 10 , 13 , 47 , 94 , 152 ,
223 , 307 , 402 , 508 , 622 , 742 , 866 , 991 ,
1113 , 1229 , 1336 , 1430 , 1510 , 1571 , 1614 , 1635 ,
1635 , 1614 , 1571 , 1510 , 1430 , 1336 , 1229 , 1113 ,
991 , 866 , 742 , 622 , 508 , 402 , 307 , 223 ,
152 , 94 , 47 , 13 , - 10 , - 25 , - 33 , - 34 ,
- 32 , - 27 , - 20 , - 13 , - 7 , - 3 , 0 , 0
} } ,
2017-11-28 02:52:04 -05:00
} ; */
/* CTCSS audio filter */
/* 24kHz int16_t input
* - > FIR filter , < 300 Hz pass , > 300 Hz stop , gain of 1
* - > 12 kHz int16_t output , gain of 1.0 ( I think ) .
* Padded to multiple of four taps for unrolled FIR code .
* sum ( abs ( taps ) ) : 125270
*/
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 64 > taps_64_lp_025_025 {
. low_frequency_normalized = 0 ,
. high_frequency_normalized = 0 ,
. transition_normalized = 0 ,
. taps = { { 0 , 0 , 2 , 6 , 12 , 20 , 32 , 46 ,
64 , 85 , 110 , 138 , 169 , 204 , 241 , 281 ,
323 , 367 , 412 , 457 , 502 , 547 , 590 , 631 ,
669 , 704 , 735 , 762 , 784 , 801 , 812 , 818 ,
818 , 812 , 801 , 784 , 762 , 735 , 704 , 669 ,
631 , 590 , 547 , 502 , 457 , 412 , 367 , 323 ,
281 , 241 , 204 , 169 , 138 , 110 , 85 , 64 ,
46 , 32 , 20 , 12 , 6 , 2 , 0 , 0 } } ,
2017-11-28 02:52:04 -05:00
} ;
2015-12-30 15:19:42 -05:00
// DSB AM 6K00A3E emission type ///////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=3000, stop=339000, decim=8, fout=384000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 24 > taps_6k0_decim_0 {
. low_frequency_normalized = - 3000.0f / 3072000.0f ,
. high_frequency_normalized = 3000.0f / 3072000.0f ,
. transition_normalized = 336000.0f / 3072000.0f ,
. taps = { {
39 ,
104 ,
224 ,
412 ,
674 ,
1008 ,
1400 ,
1821 ,
2234 ,
2594 ,
2863 ,
3006 ,
3006 ,
2863 ,
2594 ,
2234 ,
1821 ,
1400 ,
1008 ,
674 ,
412 ,
224 ,
104 ,
39 ,
} } ,
2015-12-30 15:19:42 -05:00
} ;
// IFIR prototype filter: fs=384000, pass=3000, stop=45000, decim=8, fout=48000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_6k0_decim_1 {
. low_frequency_normalized = - 3000.0f / 384000.0f ,
. high_frequency_normalized = 3000.0f / 384000.0f ,
. transition_normalized = 43000.0f / 384000.0f ,
. taps = { {
- 26 ,
- 63 ,
- 123 ,
- 195 ,
- 263 ,
- 295 ,
- 253 ,
- 99 ,
199 ,
651 ,
1242 ,
1927 ,
2633 ,
3273 ,
3760 ,
4023 ,
4023 ,
3760 ,
3273 ,
2633 ,
1927 ,
1242 ,
651 ,
199 ,
- 99 ,
- 253 ,
- 295 ,
- 263 ,
- 195 ,
- 123 ,
- 63 ,
- 26 ,
} } ,
2015-12-30 15:19:42 -05:00
} ;
2016-01-30 22:03:50 -05:00
// IFIR prototype filter: fs=48000, pass=3000, stop=6700, decim=4, fout=12000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_6k0_decim_2 {
. low_frequency_normalized = - 3000.0f / 48000.0f ,
. high_frequency_normalized = 3000.0f / 48000.0f ,
. transition_normalized = 3700.0f / 48000.0f ,
. taps = { {
95 ,
178 ,
247 ,
208 ,
- 21 ,
- 474 ,
- 1080 ,
- 1640 ,
- 1857 ,
- 1411 ,
- 83 ,
2134 ,
4978 ,
7946 ,
10413 ,
11815 ,
11815 ,
10413 ,
7946 ,
4978 ,
2134 ,
- 83 ,
- 1411 ,
- 1857 ,
- 1640 ,
- 1080 ,
- 474 ,
- 21 ,
208 ,
247 ,
178 ,
95 ,
} } ,
} ;
2022-11-13 18:32:29 -05:00
2022-11-19 12:17:54 -05:00
// IFIR prototype filter fs=48000 ; pass=4500 (cutt off -3dBs) , stop=8000 (<-60dBs), decim=4, fout=12000
2023-05-18 16:16:05 -04:00
// For Europe AM commercial broadcasting stations in LF/MF/HF, Emissions Designator 9K00A3E Bandwidth: 9.00 kHz (derivated from taps_6k0_decim_2 )
// Pre-decimate LPF FIR filter design Created with SciPy Python with the "window method", num_taps = 32, cut_off = 5150. sample_rate = 48000 # Hz,
2022-11-19 12:17:54 -05:00
// Created with h = signal.firwin(num_taps, cut_off, nyq=sample_rate/2, window=('chebwin',50)) , achieving good STOP band plot < -60 dB's with some ripple.
// post-scaled h taps to avoid decimals , targeting <= similar int values as previous taps_6k0_dsb_channel peak < 32.767 (2 exp 15) and similar H(f)gain
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 32 > taps_9k0_decim_2 {
. low_frequency_normalized = - 4500.0f / 48000.0f , // Negative -cutt off freq -3dB (real achieved data ,in the plot and measurements)
. high_frequency_normalized = 4500.0f / 48000.0f , // Positive +cutt off freq -3dB (idem)
. transition_normalized = 3500.0f / 48000.0f , // 3500 Hz = (8000 Hz - 4500 Hz) (both from plot H(f) curve plot)
. taps = { { - 53 , - 30 , 47 , 198 , 355 , 372 , 89 , - 535 ,
- 1307 , - 1771 , - 1353 , 370 , 3384 , 7109 , 10535 , 12591 ,
12591 , 10535 , 7109 , 3384 , 370 , - 1353 , - 1771 , - 1307 ,
- 535 , 89 , 372 , 355 , 198 , 47 , - 30 , - 53 } } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2016-01-30 23:45:16 -05:00
// Channel filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
/* NOTE: Slightly less than 1.0 gain (normalized to 65536) due to max(taps) being
* slightly larger than 32767 ( 33312 ) .
2023-05-18 16:16:05 -04:00
*/
constexpr fir_taps_complex < 64 > taps_6k0_dsb_channel {
. low_frequency_normalized = - 3000.0f / 12000.0f ,
. high_frequency_normalized = 3000.0f / 12000.0f ,
. transition_normalized = 300.0f / 12000.0f ,
. taps = { {
{ - 69 , 0 } ,
{ - 140 , 0 } ,
{ 119 , 0 } ,
{ 89 , 0 } ,
{ - 132 , 0 } ,
{ - 134 , 0 } ,
{ 197 , 0 } ,
{ 167 , 0 } ,
{ - 273 , 0 } ,
{ - 206 , 0 } ,
{ 372 , 0 } ,
{ 247 , 0 } ,
{ - 497 , 0 } ,
{ - 289 , 0 } ,
{ 654 , 0 } ,
{ 331 , 0 } ,
{ - 854 , 0 } ,
{ - 372 , 0 } ,
{ 1112 , 0 } ,
{ 411 , 0 } ,
{ - 1455 , 0 } ,
{ - 446 , 0 } ,
{ 1933 , 0 } ,
{ 476 , 0 } ,
{ - 2654 , 0 } ,
{ - 501 , 0 } ,
{ 3902 , 0 } ,
{ 520 , 0 } ,
{ - 6717 , 0 } ,
{ - 531 , 0 } ,
{ 20478 , 0 } ,
{ 32767 , 0 } ,
{ 20478 , 0 } ,
{ - 531 , 0 } ,
{ - 6717 , 0 } ,
{ 520 , 0 } ,
{ 3902 , 0 } ,
{ - 501 , 0 } ,
{ - 2654 , 0 } ,
{ 476 , 0 } ,
{ 1933 , 0 } ,
{ - 446 , 0 } ,
{ - 1455 , 0 } ,
{ 411 , 0 } ,
{ 1112 , 0 } ,
{ - 372 , 0 } ,
{ - 854 , 0 } ,
{ 331 , 0 } ,
{ 654 , 0 } ,
{ - 289 , 0 } ,
{ - 497 , 0 } ,
{ 247 , 0 } ,
{ 372 , 0 } ,
{ - 206 , 0 } ,
{ - 273 , 0 } ,
{ 167 , 0 } ,
{ 197 , 0 } ,
{ - 134 , 0 } ,
{ - 132 , 0 } ,
{ 89 , 0 } ,
{ 119 , 0 } ,
{ - 140 , 0 } ,
{ - 69 , 0 } ,
{ 0 , 0 } ,
} } ,
2016-01-30 22:03:32 -05:00
} ;
2022-11-19 12:17:54 -05:00
// Channel filter: fs=12000, pass=4500 (cutt off -3dBs), stop=4940 (<-60dBs), decim=1, fout=12000 (*1) real frec pass / stop , based on plotted H(f) curve)
2023-05-18 16:16:05 -04:00
// For Europe AM commercial broadcasting stations in LF/MF/HF, Emissions Designator 9K00A3E Bandwidth: 9.00 kHz (derivative from taps_6k0_dsb_channel)
// FIR filter design created with SciPy Python using "window method"; selected design parameters: num_taps = 64, cut_off = 4575. sample_rate = 12000 # Hz,
2022-11-19 12:17:54 -05:00
// Created with : h = signal.firwin(num_taps, cut_off, nyq=sample_rate/2, window=('chebwin',50)) , achieving real plot curve (*1) with peak stop band ripple -60dBs.
// post-scaled h taps to avoid decimals , targeting <= similar int values as previous taps_6k0_dsb_channel peak < 32.767 (2 exp 15), (29625) and similar H(f)gain
2023-05-18 16:16:05 -04:00
constexpr fir_taps_complex < 64 > taps_9k0_dsb_channel {
. low_frequency_normalized = - 4500.0f / 12000.0f , // Negative -cutt off freq -3dB (in the H(f) curve plot)
. high_frequency_normalized = 4500.0f / 12000.0f , // Positive +cutt off freq -3dB (in the H(f) curve plot)
. transition_normalized = 440.0f / 12000.0f , // 440Hz = (4940 Hz -4500 Hz) cut-3dB's (both data comes from H(f) curve plot and confirmed by measurements )
. taps = { {
{ 2 , 0 } ,
{ - 18 , 0 } ,
{ 34 , 0 } ,
{ - 33 , 0 } ,
{ 6 , 0 } ,
{ 44 , 0 } ,
{ - 91 , 0 } ,
{ 96 , 0 } ,
{ - 35 , 0 } ,
{ - 80 , 0 } ,
{ 193 , 0 } ,
{ - 223 , 0 } ,
{ 116 , 0 } ,
{ 112 , 0 } ,
{ - 353 , 0 } ,
{ 452 , 0 } ,
{ - 293 , 0 } ,
{ - 111 , 0 } ,
{ 584 , 0 } ,
{ - 844 , 0 } ,
{ 653 , 0 } ,
{ 22 , 0 } ,
{ - 921 , 0 } ,
{ 1554 , 0 } ,
{ - 1422 , 0 } ,
{ 301 , 0 } ,
{ 1533 , 0 } ,
{ - 3282 , 0 } ,
{ 3804 , 0 } ,
{ - 1819 , 0 } ,
{ - 4605 , 0 } ,
{ 29625 , 0 } ,
{ 29625 , 0 } ,
{ - 4605 , 0 } ,
{ - 1819 , 0 } ,
{ 3804 , 0 } ,
{ - 3282 , 0 } ,
{ 1533 , 0 } ,
{ 301 , 0 } ,
{ - 1422 , 0 } ,
{ 1554 , 0 } ,
{ - 921 , 0 } ,
{ 22 , 0 } ,
{ 653 , 0 } ,
{ - 844 , 0 } ,
{ 584 , 0 } ,
{ - 111 , 0 } ,
{ - 293 , 0 } ,
{ 452 , 0 } ,
{ - 353 , 0 } ,
{ 112 , 0 } ,
{ 116 , 0 } ,
{ - 223 , 0 } ,
{ 193 , 0 } ,
{ - 80 , 0 } ,
{ - 35 , 0 } ,
{ 96 , 0 } ,
{ - 91 , 0 } ,
{ 44 , 0 } ,
{ 6 , 0 } ,
{ - 33 , 0 } ,
{ 34 , 0 } ,
{ - 18 , 0 } ,
{ 2 , 0 } ,
} } ,
2022-11-13 18:32:29 -05:00
} ;
2016-01-30 01:29:52 -05:00
// USB AM 2K80J3E emission type ///////////////////////////////////////////
2016-01-30 20:22:38 -05:00
// IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_complex < 64 > taps_2k8_usb_channel {
. low_frequency_normalized = 0 ,
. high_frequency_normalized = 3000.0f / 12000.0f ,
. transition_normalized = 300.0f / 12000.0f ,
. taps = { {
{ - 146 , 0 } ,
{ - 41 , - 45 } ,
{ - 1 , 10 } ,
{ - 95 , 69 } ,
{ - 194 , - 41 } ,
{ - 91 , - 158 } ,
{ 14 , - 43 } ,
{ - 150 , 67 } ,
{ - 299 , - 133 } ,
{ - 100 , - 307 } ,
{ 50 , - 86 } ,
{ - 254 , 54 } ,
{ - 453 , - 329 } ,
{ - 62 , - 587 } ,
{ 170 , - 189 } ,
{ - 334 , 0 } ,
{ - 580 , - 645 } ,
{ 104 , - 986 } ,
{ 418 , - 304 } ,
{ - 412 , - 88 } ,
{ - 680 , - 1178 } ,
{ 527 , - 1623 } ,
{ 970 , - 432 } ,
{ - 441 , - 196 } ,
{ - 698 , - 2149 } ,
{ 1617 , - 2800 } ,
{ 2384 , - 507 } ,
{ - 429 , - 311 } ,
{ - 545 , - 5181 } ,
{ 6925 , - 7691 } ,
{ 14340 , 0 } ,
{ 10601 , 11773 } ,
{ - 1499 , 14261 } ,
{ - 8373 , 6083 } ,
{ - 5095 , - 1083 } ,
{ - 265 , - 459 } ,
{ - 753 , 2318 } ,
{ - 2954 , 1315 } ,
{ - 2064 , - 919 } ,
{ - 149 , - 459 } ,
{ - 531 , 920 } ,
{ - 1669 , 355 } ,
{ - 1100 , - 800 } ,
{ - 44 , - 419 } ,
{ - 346 , 384 } ,
{ - 992 , 0 } ,
{ - 580 , - 645 } ,
{ 35 , - 332 } ,
{ - 205 , 149 } ,
{ - 577 , - 123 } ,
{ - 280 , - 485 } ,
{ 80 , - 247 } ,
{ - 91 , 40 } ,
{ - 294 , - 131 } ,
{ - 101 , - 312 } ,
{ 82 , - 142 } ,
{ - 44 , 9 } ,
{ - 147 , - 107 } ,
{ - 21 , - 197 } ,
{ 79 , - 88 } ,
{ 10 , 0 } ,
{ - 41 , - 45 } ,
{ 15 , - 145 } ,
{ 0 , 0 } ,
} } ,
2016-01-30 01:29:52 -05:00
} ;
2016-01-30 20:23:04 -05:00
// LSB AM 2K80J3E emission type ///////////////////////////////////////////
// IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_complex < 64 > taps_2k8_lsb_channel {
. low_frequency_normalized = - 3000.0f / 12000.0f ,
. high_frequency_normalized = 0 ,
. transition_normalized = 300.0f / 12000.0f ,
. taps = { {
{ - 146 , 0 } ,
{ - 41 , 45 } ,
{ - 1 , - 10 } ,
{ - 95 , - 69 } ,
{ - 194 , 41 } ,
{ - 91 , 158 } ,
{ 14 , 43 } ,
{ - 150 , - 67 } ,
{ - 299 , 133 } ,
{ - 100 , 307 } ,
{ 50 , 86 } ,
{ - 254 , - 54 } ,
{ - 453 , 329 } ,
{ - 62 , 587 } ,
{ 170 , 189 } ,
{ - 334 , 0 } ,
{ - 580 , 645 } ,
{ 104 , 986 } ,
{ 418 , 304 } ,
{ - 412 , 88 } ,
{ - 680 , 1178 } ,
{ 527 , 1623 } ,
{ 970 , 432 } ,
{ - 441 , 196 } ,
{ - 698 , 2149 } ,
{ 1617 , 2800 } ,
{ 2384 , 507 } ,
{ - 429 , 311 } ,
{ - 545 , 5181 } ,
{ 6925 , 7691 } ,
{ 14340 , 0 } ,
{ 10601 , - 11773 } ,
{ - 1499 , - 14261 } ,
{ - 8373 , - 6083 } ,
{ - 5095 , 1083 } ,
{ - 265 , 459 } ,
{ - 753 , - 2318 } ,
{ - 2954 , - 1315 } ,
{ - 2064 , 919 } ,
{ - 149 , 459 } ,
{ - 531 , - 920 } ,
{ - 1669 , - 355 } ,
{ - 1100 , 800 } ,
{ - 44 , 419 } ,
{ - 346 , - 384 } ,
{ - 992 , 0 } ,
{ - 580 , 645 } ,
{ 35 , 332 } ,
{ - 205 , - 149 } ,
{ - 577 , 123 } ,
{ - 280 , 485 } ,
{ 80 , 247 } ,
{ - 91 , - 40 } ,
{ - 294 , 131 } ,
{ - 101 , 312 } ,
{ 82 , 142 } ,
{ - 44 , - 9 } ,
{ - 147 , 107 } ,
{ - 21 , 197 } ,
{ 79 , 88 } ,
{ 10 , 0 } ,
{ - 41 , 45 } ,
{ 15 , 145 } ,
{ 0 , 0 } ,
} } ,
2016-01-30 20:23:04 -05:00
} ;
2020-08-17 09:07:06 -04:00
// USB AM 700Hz filter: fs=12000, start=600, end=800, width=200, stop=40db, decim=1, fout=12000
2023-05-18 16:16:05 -04:00
constexpr fir_taps_complex < 64 > taps_0k7_usb_channel {
. low_frequency_normalized = 600.0f / 12000.0f ,
. high_frequency_normalized = 800.0f / 12000.0f ,
. transition_normalized = 200.0f / 12000.0f ,
. taps = { {
{ 531 , 0 } ,
{ 192 , 73 } ,
{ 181 , 163 } ,
{ 129 , 254 } ,
{ 34 , 328 } ,
{ - 97 , 364 } ,
{ - 251 , 345 } ,
{ - 403 , 261 } ,
{ - 524 , 111 } ,
{ - 585 , - 92 } ,
{ - 564 , - 326 } ,
{ - 448 , - 554 } ,
{ - 239 , - 737 } ,
{ 43 , - 836 } ,
{ 366 , - 822 } ,
{ 681 , - 681 } ,
{ 936 , - 417 } ,
{ 1085 , - 56 } ,
{ 1090 , 354 } ,
{ 935 , 757 } ,
{ 629 , 1090 } ,
{ 205 , 1296 } ,
{ - 283 , 1331 } ,
{ - 766 , 1180 } ,
{ - 1172 , 851 } ,
{ - 1435 , 384 } ,
{ - 1510 , - 158 } ,
{ - 1377 , - 702 } ,
{ - 1049 , - 1165 } ,
{ - 568 , - 1480 } ,
{ 0 , - 1596 } ,
{ 574 , - 1496 } ,
{ 1072 , - 1191 } ,
{ 1422 , - 724 } ,
{ 1576 , - 165 } ,
{ 1515 , 406 } ,
{ 1251 , 908 } ,
{ 827 , 1273 } ,
{ 309 , 1453 } ,
{ - 226 , 1431 } ,
{ - 703 , 1218 } ,
{ - 1058 , 856 } ,
{ - 1248 , 405 } ,
{ - 1257 , - 65 } ,
{ - 1100 , - 489 } ,
{ - 810 , - 810 } ,
{ - 441 , - 992 } ,
{ - 53 , - 1024 } ,
{ 297 , - 916 } ,
{ 566 , - 699 } ,
{ 725 , - 418 } ,
{ 765 , - 121 } ,
{ 697 , 148 } ,
{ 546 , 355 } ,
{ 348 , 479 } ,
{ 138 , 517 } ,
{ - 50 , 477 } ,
{ - 194 , 381 } ,
{ - 280 , 252 } ,
{ - 308 , 118 } ,
{ - 285 , 0 } ,
{ - 228 , - 87 } ,
{ - 153 , - 138 } ,
{ - 241 , - 473 } ,
} } ,
2020-08-17 09:07:06 -04:00
} ;
2016-01-02 13:35:23 -05:00
// WFM 200KF8E emission type //////////////////////////////////////////////
2016-01-02 13:49:37 -05:00
// IFIR image-reject filter: fs=3072000, pass=100000, stop=484000, decim=4, fout=768000
2016-01-02 13:35:23 -05:00
constexpr fir_taps_real < 24 > taps_200k_wfm_decim_0 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 100000.0f / 3072000.0f ,
. high_frequency_normalized = 100000.0f / 3072000.0f ,
. transition_normalized = 384000.0f / 3072000.0f ,
. taps = { {
48 ,
- 18 ,
- 151 ,
- 364 ,
- 557 ,
- 548 ,
- 139 ,
789 ,
2187 ,
3800 ,
5230 ,
6071 ,
6071 ,
5230 ,
3800 ,
2187 ,
789 ,
- 139 ,
- 548 ,
- 557 ,
- 364 ,
- 151 ,
- 18 ,
48 ,
} } ,
2016-01-02 13:35:23 -05:00
} ;
2016-01-02 13:49:37 -05:00
// IFIR prototype filter: fs=768000, pass=100000, stop=284000, decim=2, fout=384000
2016-01-02 13:35:23 -05:00
constexpr fir_taps_real < 16 > taps_200k_wfm_decim_1 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 100000.0f / 768000.0f ,
. high_frequency_normalized = 100000.0f / 768000.0f ,
. transition_normalized = 184000.0f / 768000.0f ,
. taps = { {
- 67 ,
- 123 ,
388 ,
622 ,
- 1342 ,
- 2185 ,
4599 ,
14486 ,
14486 ,
4599 ,
- 2185 ,
- 1342 ,
622 ,
388 ,
- 123 ,
- 67 ,
} } ,
2016-01-02 13:35:23 -05:00
} ;
2015-07-08 11:39:24 -04:00
/* Wideband audio filter */
/* 96kHz int16_t input
* - > FIR filter , < 15 kHz ( 0.156f s ) pass , > 19 kHz ( 0.198f s ) stop
* - > 48 kHz int16_t output , gain of 1.0 ( I think ) .
* Padded to multiple of four taps for unrolled FIR code .
* sum ( abs ( taps ) ) : 125270
*/
2023-05-18 16:16:05 -04:00
constexpr fir_taps_real < 64 > taps_64_lp_156_198 {
. low_frequency_normalized = - 0.156f ,
. high_frequency_normalized = 0.156f ,
. transition_normalized = 0.04f ,
. taps = { {
- 27 ,
166 ,
104 ,
- 36 ,
- 174 ,
- 129 ,
109 ,
287 ,
148 ,
- 232 ,
- 430 ,
- 130 ,
427 ,
597 ,
49 ,
- 716 ,
- 778 ,
137 ,
1131 ,
957 ,
- 493 ,
- 1740 ,
- 1121 ,
1167 ,
2733 ,
1252 ,
- 2633 ,
- 4899 ,
- 1336 ,
8210 ,
18660 ,
23254 ,
18660 ,
8210 ,
- 1336 ,
- 4899 ,
- 2633 ,
1252 ,
2733 ,
1167 ,
- 1121 ,
- 1740 ,
- 493 ,
957 ,
1131 ,
137 ,
- 778 ,
- 716 ,
49 ,
597 ,
427 ,
- 130 ,
- 430 ,
- 232 ,
148 ,
287 ,
109 ,
- 129 ,
- 174 ,
- 36 ,
104 ,
166 ,
- 27 ,
0 ,
} } ,
2015-07-18 14:35:31 -04:00
} ;
2015-07-08 11:39:24 -04:00
2023-05-07 10:08:45 -04:00
// WFM 180kHZ General purpose filter with sharp transition , it improves Commercial WFM S/N in weak signals //////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=90000, stop=250000, decim=4, fout=768000
constexpr fir_taps_real < 24 > taps_180k_wfm_decim_0 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 90000.0f / 3072000.0f ,
. high_frequency_normalized = 90000.0f / 3072000.0f ,
. transition_normalized = 160000.0f / 3072000.0f ,
. taps = { {
55 ,
122 ,
244 ,
424 ,
666 ,
965 ,
1308 ,
1669 ,
2019 ,
2321 ,
2544 ,
2663 ,
2663 ,
2544 ,
2321 ,
2019 ,
1669 ,
1308 ,
965 ,
666 ,
424 ,
244 ,
122 ,
55 ,
} } ,
2023-05-07 10:08:45 -04:00
} ;
// IFIR prototype filter: fs=768000, pass=90000, stop=110000, decim=2, fout=384000
constexpr fir_taps_real < 16 > taps_180k_wfm_decim_1 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 90000.0f / 768000.0f ,
. high_frequency_normalized = 90000.0f / 768000.0f ,
. transition_normalized = 20000.0f / 768000.0f ,
. taps = { {
55 ,
19 ,
- 356 ,
- 916 ,
- 529 ,
2139 ,
6695 ,
10392 ,
10392 ,
6695 ,
2139 ,
- 529 ,
- 916 ,
- 356 ,
19 ,
55 ,
} } ,
2023-05-07 10:08:45 -04:00
} ;
// WFM 40kHZ filter for NOAA APT reception in 137Mhz band with sharp transition //////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=20000, stop=97000, decim=4, fout=768000
constexpr fir_taps_real < 24 > taps_40k_wfm_decim_0 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 20000.0f / 3072000.0f ,
. high_frequency_normalized = 20000.0f / 3072000.0f ,
. transition_normalized = 67000.0f / 3072000.0f ,
. taps = { {
46 ,
112 ,
230 ,
408 ,
650 ,
953 ,
1301 ,
1671 ,
2029 ,
2340 ,
2570 ,
2692 ,
2692 ,
2570 ,
2340 ,
2029 ,
1671 ,
1301 ,
953 ,
650 ,
408 ,
230 ,
112 ,
46 ,
} } ,
2023-05-07 10:08:45 -04:00
} ;
// IFIR prototype filter: fs=768000, pass=20000, stop=55000, decim=2, fout=384000
constexpr fir_taps_real < 16 > taps_40k_wfm_decim_1 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 20000.0f / 768000.0f ,
. high_frequency_normalized = 20000.0f / 768000.0f ,
. transition_normalized = 35000.0f / 768000.0f ,
. taps = { {
83 ,
299 ,
743 ,
1456 ,
2396 ,
3418 ,
4297 ,
4808 ,
4808 ,
4297 ,
3418 ,
2396 ,
1456 ,
743 ,
299 ,
83 ,
} } ,
2023-05-07 10:08:45 -04:00
} ;
2016-04-11 13:18:31 -04:00
// TPMS decimation filters ////////////////////////////////////////////////
// IFIR image-reject filter: fs=2457600, pass=100000, stop=407200, decim=4, fout=614400
static constexpr fir_taps_real < 24 > taps_200k_decim_0 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 100000.0f / 2457600.0f ,
. high_frequency_normalized = 100000.0f / 2457600.0f ,
. transition_normalized = 307200.0f / 2457600.0f ,
. taps = { {
90 ,
94 ,
4 ,
- 240 ,
- 570 ,
- 776 ,
- 563 ,
309 ,
1861 ,
3808 ,
5618 ,
6710 ,
6710 ,
5618 ,
3808 ,
1861 ,
309 ,
- 563 ,
- 776 ,
- 570 ,
- 240 ,
4 ,
94 ,
90 ,
} } ,
2016-04-11 13:18:31 -04:00
} ;
// IFIR prototype filter: fs=614400, pass=100000, stop=207200, decim=2, fout=307200
static constexpr fir_taps_real < 16 > taps_200k_decim_1 = {
2023-05-18 16:16:05 -04:00
. low_frequency_normalized = - 100000.0f / 614400.0f ,
. high_frequency_normalized = 100000.0f / 614400.0f ,
. transition_normalized = 107200.0f / 614400.0f ,
. taps = { {
- 132 ,
- 256 ,
545 ,
834 ,
- 1507 ,
- 2401 ,
4666 ,
14583 ,
14583 ,
4666 ,
- 2401 ,
- 1507 ,
834 ,
545 ,
- 256 ,
- 132 ,
} } ,
2016-04-11 13:18:31 -04:00
} ;
2023-11-11 20:43:10 -05:00
// BTLE RX decimation filters ////////////////////////////////////////////////
// Default BTLE filter, it is supporting 1M PHY.
// IFIR image-reject filter: fs=4000000, pass=430000, stop=825000, decim=4, fout=1000000
// 1M PHY, This one it is for the classic bluetooth , (BW = 1Mhz : +-500k, channel space is 2Mhz)
// The traditional transmission of 1 Mbit in the Bluetooth Basic Rate was renamed 1M PHY
static constexpr fir_taps_real < 24 > taps_BTLE_1M_PHY_decim_0 = {
. low_frequency_normalized = - 430000.0f / 4000000.0f ,
. high_frequency_normalized = 430000.0f / 4000000.0f ,
. transition_normalized = 395000.0f / 4000000.0f ,
. taps = { {
12 ,
57 ,
112 ,
83 ,
- 139 ,
- 531 ,
- 813 ,
- 507 ,
766 ,
2916 ,
5255 ,
6788 ,
6788 ,
5255 ,
2916 ,
766 ,
- 507 ,
- 813 ,
- 531 ,
- 139 ,
83 ,
112 ,
57 ,
12 ,
} } ,
} ;
// IFIR image-reject filter: fs=4000000, pass=920000, stop=1350000, decim=4, fout=1000000
// Alternative filter, Note : in local test, it improves slightly the sensitivity compared to above filter, but it should have aliasing if co-adjacent channels.
// Then , we leave that filter in the code ,as experimental , but it should not be set up as default one.
// It may work well, in areas where we just receive few signals, without adjacent channels and weak far away signals.
// 2M PHY , Bluetooth 5 has introduced a new transmission mode with a doubled symbol rate.
// Bluetooth LE has been traditionally transmitting 1 bit per symbol so that theoretically the data rate doubles as well. (BW 2Mhz : +-1Mhz, channel space 2Mhz)
static constexpr fir_taps_real < 24 > taps_BTLE_2M_PHY_decim_0 = {
. low_frequency_normalized = - 920000.0f / 4000000.0f ,
. high_frequency_normalized = 920000.0f / 4000000.0f ,
. transition_normalized = 430000.0f / 4000000.0f ,
. taps = { {
- 8 ,
- 20 ,
42 ,
81 ,
- 142 ,
- 234 ,
371 ,
573 ,
- 884 ,
- 1414 ,
2573 ,
8062 ,
8062 ,
2573 ,
- 1414 ,
- 884 ,
573 ,
371 ,
- 234 ,
- 142 ,
81 ,
42 ,
- 20 ,
- 8 ,
} } ,
} ;
2023-05-18 16:16:05 -04:00
# endif /*__DSP_FIR_TAPS_H__*/