diff --git a/firmware/application/ui/ui_spectrum.cpp b/firmware/application/ui/ui_spectrum.cpp index 2a458b96..878b3c1f 100644 --- a/firmware/application/ui/ui_spectrum.cpp +++ b/firmware/application/ui/ui_spectrum.cpp @@ -94,13 +94,16 @@ void FrequencyScale::set_spectrum_sampling_rate(const int new_sampling_rate) { } void FrequencyScale::set_channel_filter( - const int pass_frequency, - const int stop_frequency + const int low_frequency, + const int high_frequency, + const int transition ) { - if( (channel_filter_pass_frequency != pass_frequency) || - (channel_filter_stop_frequency != stop_frequency) ) { - channel_filter_pass_frequency = pass_frequency; - channel_filter_stop_frequency = stop_frequency; + if( (channel_filter_low_frequency != low_frequency) || + (channel_filter_high_frequency != high_frequency) || + (channel_filter_transition != transition) ) { + channel_filter_low_frequency = low_frequency; + channel_filter_high_frequency = high_frequency; + channel_filter_transition = transition; set_dirty(); } } @@ -184,41 +187,28 @@ void FrequencyScale::draw_frequency_ticks(Painter& painter, const Rect r) { } void FrequencyScale::draw_filter_ranges(Painter& painter, const Rect r) { - if( channel_filter_pass_frequency ) { + if( channel_filter_low_frequency != channel_filter_high_frequency ) { const auto x_center = r.width() / 2; - const auto pass_offset = channel_filter_pass_frequency * spectrum_bins / spectrum_sampling_rate; - const auto stop_offset = channel_filter_stop_frequency * spectrum_bins / spectrum_sampling_rate; + const auto x_low = x_center + channel_filter_low_frequency * spectrum_bins / spectrum_sampling_rate; + const auto x_high = x_center + channel_filter_high_frequency * spectrum_bins / spectrum_sampling_rate; - const auto pass_x_lo = x_center - pass_offset; - const auto pass_x_hi = x_center + pass_offset; + if( channel_filter_transition ) { + const auto trans = channel_filter_transition * spectrum_bins / spectrum_sampling_rate; - if( channel_filter_stop_frequency ) { - const auto stop_x_lo = x_center - stop_offset; - const auto stop_x_hi = x_center + stop_offset; - - const Rect r_stop_lo { - r.left() + stop_x_lo, r.bottom() - filter_band_height, - pass_x_lo - stop_x_lo, filter_band_height + const Rect r_all { + r.left() + x_low - trans, r.bottom() - filter_band_height, + x_high - x_low + trans*2, filter_band_height }; painter.fill_rectangle( - r_stop_lo, - Color::yellow() - ); - - const Rect r_stop_hi { - r.left() + pass_x_hi, r.bottom() - filter_band_height, - stop_x_hi - pass_x_hi, filter_band_height - }; - painter.fill_rectangle( - r_stop_hi, + r_all, Color::yellow() ); } const Rect r_pass { - r.left() + pass_x_lo, r.bottom() - filter_band_height, - pass_x_hi - pass_x_lo, filter_band_height + r.left() + x_low, r.bottom() - filter_band_height, + x_high - x_low, filter_band_height }; painter.fill_rectangle( r_pass, @@ -390,8 +380,9 @@ void WaterfallWidget::on_channel_spectrum(const ChannelSpectrum& spectrum) { sampling_rate = spectrum.sampling_rate; frequency_scale.set_spectrum_sampling_rate(sampling_rate); frequency_scale.set_channel_filter( - spectrum.channel_filter_pass_frequency, - spectrum.channel_filter_stop_frequency + spectrum.channel_filter_low_frequency, + spectrum.channel_filter_high_frequency, + spectrum.channel_filter_transition ); } diff --git a/firmware/application/ui/ui_spectrum.hpp b/firmware/application/ui/ui_spectrum.hpp index 42579107..1ba8b4a3 100644 --- a/firmware/application/ui/ui_spectrum.hpp +++ b/firmware/application/ui/ui_spectrum.hpp @@ -82,7 +82,7 @@ public: bool on_key(const KeyEvent key) override; void set_spectrum_sampling_rate(const int new_sampling_rate); - void set_channel_filter(const int pass_frequency, const int stop_frequency); + void set_channel_filter(const int low_frequency, const int high_frequency, const int transition); void paint(Painter& painter) override; @@ -96,8 +96,9 @@ private: SignalToken signal_token_tick_second { }; int spectrum_sampling_rate { 0 }; const int spectrum_bins = std::tuple_size::value; - int channel_filter_pass_frequency { 0 }; - int channel_filter_stop_frequency { 0 }; + int channel_filter_low_frequency { 0 }; + int channel_filter_high_frequency { 0 }; + int channel_filter_transition { 0 }; void clear(); void clear_background(Painter& painter, const Rect r); diff --git a/firmware/baseband/proc_am_audio.cpp b/firmware/baseband/proc_am_audio.cpp index 017ec4f6..23bbbcb1 100644 --- a/firmware/baseband/proc_am_audio.cpp +++ b/firmware/baseband/proc_am_audio.cpp @@ -35,7 +35,7 @@ void NarrowbandAMAudio::execute(const buffer_c8_t& buffer) { const auto decim_0_out = decim_0.execute(buffer, dst_buffer); const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); - channel_spectrum.feed(decim_1_out, channel_filter_pass_f, channel_filter_stop_f); + channel_spectrum.feed(decim_1_out, channel_filter_low_f, channel_filter_high_f, channel_filter_transition); const auto decim_2_out = decim_2.execute(decim_1_out, dst_buffer); const auto channel_out = channel_filter.execute(decim_2_out, dst_buffer); @@ -93,8 +93,9 @@ void NarrowbandAMAudio::configure(const AMConfigureMessage& message) { decim_1.configure(message.decim_1_filter.taps, 131072); decim_2.configure(message.decim_2_filter.taps, decim_2_decimation_factor); channel_filter.configure(message.channel_filter.taps, channel_filter_decimation_factor); - channel_filter_pass_f = message.channel_filter.pass_frequency_normalized * channel_filter_input_fs; - channel_filter_stop_f = message.channel_filter.stop_frequency_normalized * channel_filter_input_fs; + channel_filter_low_f = message.channel_filter.low_frequency_normalized * channel_filter_input_fs; + channel_filter_high_f = message.channel_filter.high_frequency_normalized * channel_filter_input_fs; + channel_filter_transition = message.channel_filter.transition_normalized * channel_filter_input_fs; channel_spectrum.set_decimation_factor(1.0f); modulation_ssb = (message.modulation == AMConfigureMessage::Modulation::SSB); audio_output.configure(message.audio_hpf_config); diff --git a/firmware/baseband/proc_am_audio.hpp b/firmware/baseband/proc_am_audio.hpp index a854d10a..48372904 100644 --- a/firmware/baseband/proc_am_audio.hpp +++ b/firmware/baseband/proc_am_audio.hpp @@ -64,8 +64,9 @@ private: dsp::decimate::FIRC16xR16x32Decim8 decim_1 { }; dsp::decimate::FIRAndDecimateComplex decim_2 { }; dsp::decimate::FIRAndDecimateComplex channel_filter { }; - uint32_t channel_filter_pass_f = 0; - uint32_t channel_filter_stop_f = 0; + int32_t channel_filter_low_f = 0; + int32_t channel_filter_high_f = 0; + int32_t channel_filter_transition = 0; bool modulation_ssb = false; dsp::demodulate::AM demod_am { }; diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index 1d50cd7c..41039484 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -52,7 +52,7 @@ void CaptureProcessor::execute(const buffer_c8_t& buffer) { spectrum_samples += channel.count; if( spectrum_samples >= spectrum_interval_samples ) { spectrum_samples -= spectrum_interval_samples; - channel_spectrum.feed(channel, channel_filter_pass_f, channel_filter_stop_f); + channel_spectrum.feed(channel, channel_filter_low_f, channel_filter_high_f, channel_filter_transition); } } @@ -85,8 +85,9 @@ void CaptureProcessor::samplerate_config(const SamplerateConfigMessage& message) size_t decim_1_input_fs = decim_0_output_fs; size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor; - channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667 - channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333 + channel_filter_low_f = taps_200k_decim_1.low_frequency_normalized * decim_1_input_fs; + channel_filter_high_f = taps_200k_decim_1.high_frequency_normalized * decim_1_input_fs; + channel_filter_transition = taps_200k_decim_1.transition_normalized * decim_1_input_fs; spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz; spectrum_samples = 0; diff --git a/firmware/baseband/proc_capture.hpp b/firmware/baseband/proc_capture.hpp index 9dd02d9b..2710b81b 100644 --- a/firmware/baseband/proc_capture.hpp +++ b/firmware/baseband/proc_capture.hpp @@ -60,8 +60,9 @@ private: dsp::decimate::FIRC8xR16x24FS4Decim4 decim_0 { }; dsp::decimate::FIRC16xR16x16Decim2 decim_1 { }; - uint32_t channel_filter_pass_f = 0; - uint32_t channel_filter_stop_f = 0; + int32_t channel_filter_low_f = 0; + int32_t channel_filter_high_f = 0; + int32_t channel_filter_transition = 0; std::unique_ptr stream { }; diff --git a/firmware/baseband/proc_gps_sim.cpp b/firmware/baseband/proc_gps_sim.cpp index 344332fc..83b68c0f 100644 --- a/firmware/baseband/proc_gps_sim.cpp +++ b/firmware/baseband/proc_gps_sim.cpp @@ -30,8 +30,9 @@ #include "utility.hpp" ReplayProcessor::ReplayProcessor() { - channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667 - channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333 + channel_filter_low_f = taps_200k_decim_1.low_frequency_normalized * 1000000; + channel_filter_high_f = taps_200k_decim_1.high_frequency_normalized * 1000000; + channel_filter_transition = taps_200k_decim_1.transition_normalized * 1000000; spectrum_samples = 0; diff --git a/firmware/baseband/proc_gps_sim.hpp b/firmware/baseband/proc_gps_sim.hpp index 440e79de..1ea5f03d 100644 --- a/firmware/baseband/proc_gps_sim.hpp +++ b/firmware/baseband/proc_gps_sim.hpp @@ -55,8 +55,9 @@ private: baseband_fs }; - uint32_t channel_filter_pass_f = 0; - uint32_t channel_filter_stop_f = 0; + int32_t channel_filter_low_f = 0; + int32_t channel_filter_high_f = 0; + int32_t channel_filter_transition = 0; std::unique_ptr stream { }; diff --git a/firmware/baseband/proc_nfm_audio.cpp b/firmware/baseband/proc_nfm_audio.cpp index 5e1ae1ac..6d1d06fd 100644 --- a/firmware/baseband/proc_nfm_audio.cpp +++ b/firmware/baseband/proc_nfm_audio.cpp @@ -39,7 +39,7 @@ void NarrowbandFMAudio::execute(const buffer_c8_t& buffer) { const auto decim_0_out = decim_0.execute(buffer, dst_buffer); const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); - channel_spectrum.feed(decim_1_out, channel_filter_pass_f, channel_filter_stop_f); + channel_spectrum.feed(decim_1_out, channel_filter_low_f, channel_filter_high_f, channel_filter_transition); const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer); @@ -145,8 +145,9 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) { decim_1.configure(message.decim_1_filter.taps, 131072); channel_filter.configure(message.channel_filter.taps, message.channel_decimation); demod.configure(demod_input_fs, message.deviation); - channel_filter_pass_f = message.channel_filter.pass_frequency_normalized * channel_filter_input_fs; - channel_filter_stop_f = message.channel_filter.stop_frequency_normalized * channel_filter_input_fs; + channel_filter_low_f = message.channel_filter.low_frequency_normalized * channel_filter_input_fs; + channel_filter_high_f = message.channel_filter.high_frequency_normalized * channel_filter_input_fs; + channel_filter_transition = message.channel_filter.transition_normalized * channel_filter_input_fs; channel_spectrum.set_decimation_factor(1.0f); audio_output.configure(message.audio_hpf_config, message.audio_deemph_config, (float)message.squelch_level / 100.0); diff --git a/firmware/baseband/proc_nfm_audio.hpp b/firmware/baseband/proc_nfm_audio.hpp index 94fb4dc1..0c78e84e 100644 --- a/firmware/baseband/proc_nfm_audio.hpp +++ b/firmware/baseband/proc_nfm_audio.hpp @@ -73,8 +73,9 @@ private: dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0 { }; dsp::decimate::FIRC16xR16x32Decim8 decim_1 { }; dsp::decimate::FIRAndDecimateComplex channel_filter { }; - uint32_t channel_filter_pass_f = 0; - uint32_t channel_filter_stop_f = 0; + int32_t channel_filter_low_f = 0; + int32_t channel_filter_high_f = 0; + int32_t channel_filter_transition = 0; // For CTCSS decoding dsp::decimate::FIR64AndDecimateBy2Real ctcss_filter { }; diff --git a/firmware/baseband/proc_replay.cpp b/firmware/baseband/proc_replay.cpp index edb93469..60999f4d 100644 --- a/firmware/baseband/proc_replay.cpp +++ b/firmware/baseband/proc_replay.cpp @@ -29,8 +29,9 @@ #include "utility.hpp" ReplayProcessor::ReplayProcessor() { - channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667 - channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333 + channel_filter_low_f = taps_200k_decim_1.low_frequency_normalized * 1000000; + channel_filter_high_f = taps_200k_decim_1.high_frequency_normalized * 1000000; + channel_filter_transition = taps_200k_decim_1.transition_normalized * 1000000; spectrum_samples = 0; @@ -70,7 +71,7 @@ void ReplayProcessor::execute(const buffer_c8_t& buffer) { spectrum_samples += buffer.count; if( spectrum_samples >= spectrum_interval_samples ) { spectrum_samples -= spectrum_interval_samples; - channel_spectrum.feed(iq_buffer, channel_filter_pass_f, channel_filter_stop_f); + channel_spectrum.feed(iq_buffer, channel_filter_low_f, channel_filter_high_f, channel_filter_transition); txprogress_message.progress = bytes_read; // Inform UI about progress txprogress_message.done = false; diff --git a/firmware/baseband/proc_replay.hpp b/firmware/baseband/proc_replay.hpp index 9edb82f7..df46315d 100644 --- a/firmware/baseband/proc_replay.hpp +++ b/firmware/baseband/proc_replay.hpp @@ -54,8 +54,9 @@ private: baseband_fs / 8 }; - uint32_t channel_filter_pass_f = 0; - uint32_t channel_filter_stop_f = 0; + int32_t channel_filter_low_f = 0; + int32_t channel_filter_high_f = 0; + int32_t channel_filter_transition = 0; std::unique_ptr stream { }; diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index 5793e479..79f27f37 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -43,7 +43,7 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) { spectrum_samples += channel.count; if( spectrum_samples >= spectrum_interval_samples ) { spectrum_samples -= spectrum_interval_samples; - channel_spectrum.feed(channel, channel_filter_pass_f, channel_filter_stop_f); + channel_spectrum.feed(channel, channel_filter_low_f, channel_filter_high_f, channel_filter_transition); } /* 384kHz complex[256] @@ -169,8 +169,9 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) { decim_0.configure(message.decim_0_filter.taps, 33554432); decim_1.configure(message.decim_1_filter.taps, 131072); - channel_filter_pass_f = message.decim_1_filter.pass_frequency_normalized * decim_1_input_fs; - channel_filter_stop_f = message.decim_1_filter.stop_frequency_normalized * decim_1_input_fs; + channel_filter_low_f = message.decim_1_filter.low_frequency_normalized * decim_1_input_fs; + channel_filter_high_f = message.decim_1_filter.high_frequency_normalized * decim_1_input_fs; + channel_filter_transition = message.decim_1_filter.transition_normalized * decim_1_input_fs; demod.configure(demod_input_fs, message.deviation); audio_filter.configure(message.audio_filter.taps); audio_output.configure(message.audio_hpf_config, message.audio_deemph_config); diff --git a/firmware/baseband/proc_wfm_audio.hpp b/firmware/baseband/proc_wfm_audio.hpp index 9498ed52..734ed9ef 100644 --- a/firmware/baseband/proc_wfm_audio.hpp +++ b/firmware/baseband/proc_wfm_audio.hpp @@ -67,8 +67,9 @@ private: dsp::decimate::FIRC8xR16x24FS4Decim4 decim_0 { }; dsp::decimate::FIRC16xR16x16Decim2 decim_1 { }; - uint32_t channel_filter_pass_f = 0; - uint32_t channel_filter_stop_f = 0; + int32_t channel_filter_low_f = 0; + int32_t channel_filter_high_f = 0; + int32_t channel_filter_transition = 0; dsp::demodulate::FM demod { }; dsp::decimate::DecimateBy2CIC4Real audio_dec_1 { }; diff --git a/firmware/baseband/proc_wideband_spectrum.cpp b/firmware/baseband/proc_wideband_spectrum.cpp index 82aba1ee..64139166 100644 --- a/firmware/baseband/proc_wideband_spectrum.cpp +++ b/firmware/baseband/proc_wideband_spectrum.cpp @@ -53,7 +53,7 @@ void WidebandSpectrum::execute(const buffer_c8_t& buffer) { }; channel_spectrum.feed( buffer_c16, - 0, 0 + 0, 0, 0 ); phase = 0; } else { diff --git a/firmware/baseband/spectrum_collector.cpp b/firmware/baseband/spectrum_collector.cpp index b43daadb..5d1687b6 100644 --- a/firmware/baseband/spectrum_collector.cpp +++ b/firmware/baseband/spectrum_collector.cpp @@ -78,12 +78,14 @@ void SpectrumCollector::set_decimation_factor( void SpectrumCollector::feed( const buffer_c16_t& channel, - const uint32_t filter_pass_frequency, - const uint32_t filter_stop_frequency + const int32_t filter_low_frequency, + const int32_t filter_high_frequency, + const int32_t filter_transition ) { // Called from baseband processing thread. - channel_filter_pass_frequency = filter_pass_frequency; - channel_filter_stop_frequency = filter_stop_frequency; + channel_filter_low_frequency = filter_low_frequency; + channel_filter_high_frequency = filter_high_frequency; + channel_filter_transition = filter_transition; channel_spectrum_decimator.feed( channel, @@ -136,8 +138,9 @@ void SpectrumCollector::update() { ChannelSpectrum spectrum; spectrum.sampling_rate = channel_spectrum_sampling_rate; - spectrum.channel_filter_pass_frequency = channel_filter_pass_frequency; - spectrum.channel_filter_stop_frequency = channel_filter_stop_frequency; + spectrum.channel_filter_low_frequency = channel_filter_low_frequency; + spectrum.channel_filter_high_frequency = channel_filter_high_frequency; + spectrum.channel_filter_transition = channel_filter_transition; for(size_t i=0; i, 256> channel_spectrum { }; uint32_t channel_spectrum_sampling_rate { 0 }; - uint32_t channel_filter_pass_frequency { 0 }; - uint32_t channel_filter_stop_frequency { 0 }; + int32_t channel_filter_low_frequency { 0 }; + int32_t channel_filter_high_frequency { 0 }; + int32_t channel_filter_transition { 0 }; void post_message(const buffer_c16_t& data); diff --git a/firmware/common/dsp_fir_taps.hpp b/firmware/common/dsp_fir_taps.hpp index e622c723..5df9f515 100644 --- a/firmware/common/dsp_fir_taps.hpp +++ b/firmware/common/dsp_fir_taps.hpp @@ -30,15 +30,17 @@ template struct fir_taps_real { - float pass_frequency_normalized; - float stop_frequency_normalized; + float low_frequency_normalized; + float high_frequency_normalized; + float transition_normalized; std::array taps; }; template struct fir_taps_complex { - float pass_frequency_normalized; - float stop_frequency_normalized; + float low_frequency_normalized; + float high_frequency_normalized; + float transition_normalized; std::array taps; }; @@ -46,8 +48,9 @@ struct fir_taps_complex { // IFIR image-reject filter: fs=3072000, pass=8000, stop=344000, decim=8, fout=384000 constexpr fir_taps_real<24> taps_16k0_decim_0 { - .pass_frequency_normalized = 8000.0f / 3072000.0f, - .stop_frequency_normalized = 344000.0f / 3072000.0f, + .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, @@ -57,8 +60,9 @@ constexpr fir_taps_real<24> taps_16k0_decim_0 { // IFIR prototype filter: fs=384000, pass=8000, stop=40000, decim=8, fout=48000 constexpr fir_taps_real<32> taps_16k0_decim_1 { - .pass_frequency_normalized = 8000.0f / 384000.0f, - .stop_frequency_normalized = 40000.0f / 384000.0f, + .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, @@ -69,8 +73,9 @@ constexpr fir_taps_real<32> taps_16k0_decim_1 { // Channel filter: fs=48000, pass=8000, stop=12400, decim=1, fout=48000 constexpr fir_taps_real<32> taps_16k0_channel { - .pass_frequency_normalized = 8000.0f / 48000.0f, - .stop_frequency_normalized = 12400.0f / 48000.0f, + .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, @@ -83,8 +88,9 @@ constexpr fir_taps_real<32> taps_16k0_channel { // IFIR image-reject filter: fs=3072000, pass=5500, stop=341500, decim=8, fout=384000 constexpr fir_taps_real<24> taps_11k0_decim_0 { - .pass_frequency_normalized = 5500.0f / 3072000.0f, - .stop_frequency_normalized = 341500.0f / 3072000.0f, + .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, @@ -94,8 +100,9 @@ constexpr fir_taps_real<24> taps_11k0_decim_0 { // IFIR prototype filter: fs=384000, pass=5500, stop=42500, decim=8, fout=48000 constexpr fir_taps_real<32> taps_11k0_decim_1 { - .pass_frequency_normalized = 5500.0f / 384000.0f, - .stop_frequency_normalized = 42500.0f / 384000.0f, + .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, @@ -106,8 +113,9 @@ constexpr fir_taps_real<32> taps_11k0_decim_1 { // Channel filter: fs=48000, pass=5500, stop=8900, decim=1, fout=48000 constexpr fir_taps_real<32> taps_11k0_channel { - .pass_frequency_normalized = 5500.0f / 48000.0f, - .stop_frequency_normalized = 8900.0f / 48000.0f, + .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, @@ -120,8 +128,9 @@ constexpr fir_taps_real<32> taps_11k0_channel { // IFIR image-reject filter: fs=3072000, pass=4250, stop=340250, decim=8, fout=384000 constexpr fir_taps_real<24> taps_4k25_decim_0 { - .pass_frequency_normalized = 4250.0f / 3072000.0f, - .stop_frequency_normalized = 340250.0f / 3072000.0f, + .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, @@ -131,8 +140,9 @@ constexpr fir_taps_real<24> taps_4k25_decim_0 { // IFIR prototype filter: fs=384000, pass=4250, stop=43750, decim=8, fout=48000 constexpr fir_taps_real<32> taps_4k25_decim_1 { - .pass_frequency_normalized = 4250.0f / 384000.0f, - .stop_frequency_normalized = 43750.0f / 384000.0f, + .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, @@ -143,8 +153,9 @@ constexpr fir_taps_real<32> taps_4k25_decim_1 { // Channel filter: fs=48000, pass=4250, stop=7900, decim=1, fout=48000 constexpr fir_taps_real<32> taps_4k25_channel { - .pass_frequency_normalized = 4250.0f / 48000.0f, - .stop_frequency_normalized = 7900.0f / 48000.0f, + .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, @@ -161,8 +172,6 @@ constexpr fir_taps_real<32> taps_4k25_channel { * sum(abs(taps)): 125270 */ /*constexpr fir_taps_real<64> taps_64_lp_025_025 { - .pass_frequency_normalized = 0.025f, - .stop_frequency_normalized = 0.025f, .taps = { { 0, 0, -3, -7, -13, -20, -27, -32, -34, -33, -25, -10, 13, 47, 94, 152, @@ -183,8 +192,9 @@ constexpr fir_taps_real<32> taps_4k25_channel { * sum(abs(taps)): 125270 */ constexpr fir_taps_real<64> taps_64_lp_025_025 { - .pass_frequency_normalized = 0.0125f, - .stop_frequency_normalized = 0.0125f, + .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, @@ -201,8 +211,9 @@ constexpr fir_taps_real<64> taps_64_lp_025_025 { // IFIR image-reject filter: fs=3072000, pass=3000, stop=339000, decim=8, fout=384000 constexpr fir_taps_real<24> taps_6k0_decim_0 { - .pass_frequency_normalized = 3000.0f / 3072000.0f, - .stop_frequency_normalized = 339000.0f / 3072000.0f, + .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, @@ -212,8 +223,9 @@ constexpr fir_taps_real<24> taps_6k0_decim_0 { // IFIR prototype filter: fs=384000, pass=3000, stop=45000, decim=8, fout=48000 constexpr fir_taps_real<32> taps_6k0_decim_1 { - .pass_frequency_normalized = 3000.0f / 384000.0f, - .stop_frequency_normalized = 45000.0f / 384000.0f, + .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, @@ -224,8 +236,9 @@ constexpr fir_taps_real<32> taps_6k0_decim_1 { // IFIR prototype filter: fs=48000, pass=3000, stop=6700, decim=4, fout=12000 constexpr fir_taps_real<32> taps_6k0_decim_2 { - .pass_frequency_normalized = 3000.0f / 48000.0f, - .stop_frequency_normalized = 6700.0f / 48000.0f, + .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, @@ -239,8 +252,9 @@ constexpr fir_taps_real<32> taps_6k0_decim_2 { * slightly larger than 32767 (33312). */ constexpr fir_taps_complex<64> taps_6k0_dsb_channel { - .pass_frequency_normalized = 3000.0f / 12000.0f, - .stop_frequency_normalized = 3300.0f / 12000.0f, + .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 }, @@ -265,8 +279,9 @@ constexpr fir_taps_complex<64> taps_6k0_dsb_channel { // IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000 constexpr fir_taps_complex<64> taps_2k8_usb_channel { - .pass_frequency_normalized = 3000.0f / 12000.0f, - .stop_frequency_normalized = 3300.0f / 12000.0f, + .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 }, @@ -291,8 +306,9 @@ constexpr fir_taps_complex<64> taps_2k8_usb_channel { // IFIR prototype filter: fs=12000, pass=3000, stop=3300, decim=1, fout=12000 constexpr fir_taps_complex<64> taps_2k8_lsb_channel { - .pass_frequency_normalized = 3000.0f / 12000.0f, - .stop_frequency_normalized = 3300.0f / 12000.0f, + .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 }, @@ -316,8 +332,9 @@ constexpr fir_taps_complex<64> taps_2k8_lsb_channel { // 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 { - .pass_frequency_normalized = 3000.0f / 12000.0f, - .stop_frequency_normalized = 3300.0f / 12000.0f, + .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 }, @@ -342,8 +359,9 @@ constexpr fir_taps_complex<64> taps_0k7_usb_channel { // IFIR image-reject filter: fs=3072000, pass=100000, stop=484000, decim=4, fout=768000 constexpr fir_taps_real<24> taps_200k_wfm_decim_0 = { - .pass_frequency_normalized = 100000.0f / 3072000.0f, - .stop_frequency_normalized = 484000.0f / 3072000.0f, + .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, @@ -353,8 +371,9 @@ constexpr fir_taps_real<24> taps_200k_wfm_decim_0 = { // IFIR prototype filter: fs=768000, pass=100000, stop=284000, decim=2, fout=384000 constexpr fir_taps_real<16> taps_200k_wfm_decim_1 = { - .pass_frequency_normalized = 100000.0f / 768000.0f, - .stop_frequency_normalized = 284000.0f / 768000.0f, + .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, @@ -369,8 +388,9 @@ constexpr fir_taps_real<16> taps_200k_wfm_decim_1 = { * sum(abs(taps)): 125270 */ constexpr fir_taps_real<64> taps_64_lp_156_198 { - .pass_frequency_normalized = 0.156f, - .stop_frequency_normalized = 0.196f, + .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, @@ -387,8 +407,9 @@ constexpr fir_taps_real<64> taps_64_lp_156_198 { // IFIR image-reject filter: fs=2457600, pass=100000, stop=407200, decim=4, fout=614400 static constexpr fir_taps_real<24> taps_200k_decim_0 = { - .pass_frequency_normalized = 100000.0f / 2457600.0f, - .stop_frequency_normalized = 407200.0f / 2457600.0f, + .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, @@ -398,8 +419,9 @@ static constexpr fir_taps_real<24> taps_200k_decim_0 = { // IFIR prototype filter: fs=614400, pass=100000, stop=207200, decim=2, fout=307200 static constexpr fir_taps_real<16> taps_200k_decim_1 = { - .pass_frequency_normalized = 100000.0f / 614400.0f, - .stop_frequency_normalized = 207200.0f / 614400.0f, + .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, diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index eeecc9d0..32a8fc7b 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -298,8 +298,9 @@ public: struct ChannelSpectrum { std::array db { { 0 } }; uint32_t sampling_rate { 0 }; - uint32_t channel_filter_pass_frequency { 0 }; - uint32_t channel_filter_stop_frequency { 0 }; + int32_t channel_filter_low_frequency { 0 }; + int32_t channel_filter_high_frequency { 0 }; + int32_t channel_filter_transition { 0 }; }; using ChannelSpectrumFIFO = FIFO;