portapack-mayhem/firmware/common/dsp_fir_taps.hpp

1346 lines
31 KiB
C++

/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* 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"
template <size_t N>
struct fir_taps_real {
float low_frequency_normalized;
float high_frequency_normalized;
float transition_normalized;
std::array<int16_t, N> taps;
};
template <size_t N>
struct fir_taps_complex {
float low_frequency_normalized;
float high_frequency_normalized;
float transition_normalized;
std::array<complex16_t, N> taps;
};
// NBFM 16K0F3E emission type /////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=8000, stop=344000, decim=8, fout=384000
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,
}},
};
// IFIR prototype filter: fs=384000, pass=8000, stop=40000, decim=8, fout=48000
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,
}},
};
// Channel filter: fs=48000, pass=8000, stop=12400, decim=1, fout=48000
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,
}},
};
// NBFM 11K0F3E emission type /////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=5500, stop=341500, decim=8, fout=384000
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,
}},
};
// IFIR prototype filter: fs=384000, pass=5500, stop=42500, decim=8, fout=48000
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,
}},
};
// Channel filter: fs=48000, pass=5500, stop=8900, decim=1, fout=48000
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,
}},
};
// NBFM 8K50F3E emission type /////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=4250, stop=340250, decim=8, fout=384000
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,
}},
};
// IFIR prototype filter: fs=384000, pass=4250, stop=43750, decim=8, fout=48000
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,
}},
};
// Channel filter: fs=48000, pass=4250, stop=7900, decim=1, fout=48000
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,
}},
};
/* CTCSS audio filter */
/* 12kHz int16_t input
* -> FIR filter, <300Hz pass, >300Hz stop, gain of 1
* -> 6kHz 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 {
.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
} },
};*/
/* CTCSS audio filter */
/* 24kHz int16_t input
* -> FIR filter, <300Hz pass, >300Hz stop, gain of 1
* -> 12kHz 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{
.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}},
};
// DSB AM 6K00A3E emission type ///////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=3000, stop=339000, decim=8, fout=384000
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,
}},
};
// IFIR prototype filter: fs=384000, pass=3000, stop=45000, decim=8, fout=48000
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,
}},
};
// IFIR prototype filter: fs=48000, pass=3000, stop=6700, decim=4, fout=12000
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,
}},
};
// IFIR prototype filter fs=48000 ; pass=4500 (cutt off -3dBs) , stop=8000 (<-60dBs), decim=4, fout=12000
// 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,
// 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
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}},
};
// 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).
*/
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},
}},
};
// 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)
// 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,
// 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
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},
}},
};
// USB AM 2K80J3E emission type ///////////////////////////////////////////
// IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
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},
}},
};
// LSB AM 2K80J3E emission type ///////////////////////////////////////////
// IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000
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},
}},
};
// USB AM 700Hz filter: fs=12000, start=600, end=800, width=200, stop=40db, decim=1, fout=12000
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},
}},
};
// WFM 200KF8E emission type //////////////////////////////////////////////
// IFIR image-reject filter: fs=3072000, pass=100000, stop=484000, decim=4, fout=768000
constexpr fir_taps_real<24> taps_200k_wfm_decim_0 = {
.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,
}},
};
// IFIR prototype filter: fs=768000, pass=100000, stop=284000, decim=2, fout=384000
constexpr fir_taps_real<16> taps_200k_wfm_decim_1 = {
.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,
}},
};
/* Wideband audio filter */
/* 96kHz int16_t input
* -> FIR filter, <15kHz (0.156fs) pass, >19kHz (0.198fs) stop
* -> 48kHz 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_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,
}},
};
// 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 = {
.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,
}},
};
// IFIR prototype filter: fs=768000, pass=90000, stop=110000, decim=2, fout=384000
constexpr fir_taps_real<16> taps_180k_wfm_decim_1 = {
.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,
}},
};
// 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 = {
.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,
}},
};
// IFIR prototype filter: fs=768000, pass=20000, stop=55000, decim=2, fout=384000
constexpr fir_taps_real<16> taps_40k_wfm_decim_1 = {
.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,
}},
};
// 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 = {
.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,
}},
};
// IFIR prototype filter: fs=614400, pass=100000, stop=207200, decim=2, fout=307200
static constexpr fir_taps_real<16> taps_200k_decim_1 = {
.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,
}},
};
// 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,
}},
};
#endif /*__DSP_FIR_TAPS_H__*/