mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2024-12-23 16:37:43 +00:00
033c4e9a5b
* Updated style * Updated files * fixed new line * Updated spacing * File fix WIP * Updated to clang 13 * updated comment style * Removed old comment code
1268 lines
28 KiB
C++
1268 lines
28 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,
|
|
}},
|
|
};
|
|
|
|
#endif /*__DSP_FIR_TAPS_H__*/
|