Imrpoved sound quality in analog_audio_app, and added Nyquist protection option to BBW filter for praline. (#3054)

This commit is contained in:
stafur
2026-02-28 17:36:01 -05:00
committed by GitHub
parent b013e68b17
commit 3a54b112ec
7 changed files with 225 additions and 74 deletions
+28 -6
View File
@@ -326,12 +326,23 @@ void ReceiverModel::update_baseband_bandwidth() {
if (enabled_) {
#ifdef PRALINE
/*
* PRALINE LPF bandwidth calculation from GSG hackrf_usb radio.c:
* PRALINE LPF bandwidth calculation from GSG hackrf_usb radio.c
*
* Base: (sample_rate * 3) / 8
* If quarter-shift enabled: add (AFE_rate / 8) * 2
* The LPF should be set to capture the desired signal bandwidth
* while the FPGA decimation filter handles anti-aliasing.
*
* For most modes: LPF = (output_sample_rate * 3) / 8
* For quarter-shift: add offset for shifted spectrum
*
* Note: MAX2831 minimum LPF is 11.6 MHz, so for narrow sample rates
* the hardware limit applies and FPGA filter does the real work.
*/
uint32_t sample_rate = sampling_rate();
uint8_t resampling_n = portapack::clock_manager.get_resampling_n();
uint32_t afe_rate = sample_rate << resampling_n;
// Base LPF: enough to capture desired bandwidth
uint32_t lpf_bandwidth = (sample_rate * 3) / 8;
// Check if quarter-shift is enabled (FPGA register 1, bits 2-3)
@@ -339,12 +350,23 @@ void ReceiverModel::update_baseband_bandwidth() {
uint8_t quarter_shift = (fpga_ctrl >> 2) & 0x03;
if (quarter_shift != 0) {
// Get resampling factor from clock manager
uint8_t resampling_n = portapack::clock_manager.get_resampling_n();
uint32_t offset = (sample_rate << resampling_n) / 8; // AFE_rate / 8
// Quarter-shift moves spectrum by AFE_rate/4, need wider LPF
uint32_t offset = afe_rate / 8;
lpf_bandwidth += offset * 2;
}
// For best anti-alias performance, also consider AFE Nyquist
// If our calculated LPF is below MAX2831 minimum, it doesn't matter
// But if we can set LPF to just below AFE Nyquist, that's optimal
uint32_t afe_nyquist = afe_rate / 2;
// Use the larger of: signal bandwidth requirement OR Nyquist protection
// (but MAX2831 driver will clamp to its available settings anyway)
if (lpf_bandwidth < afe_nyquist) {
// Set LPF close to Nyquist for maximum alias rejection
lpf_bandwidth = (afe_nyquist * 9) / 10; // 90% of Nyquist
}
radio::set_baseband_filter_bandwidth_rx(lpf_bandwidth);
#else
radio::set_baseband_filter_bandwidth_rx(baseband_bandwidth());