[fix](trx-rs): remove wfm denoise and default stereo audio
Co-authored-by: Codex <codex@openai.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -1259,12 +1259,6 @@ function render(update) {
|
|||||||
saveSetting("wfmAudioMode", nextMode);
|
saveSetting("wfmAudioMode", nextMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wfmDenoiseBtn && typeof update.filter.wfm_denoise === "boolean") {
|
|
||||||
const on = update.filter.wfm_denoise;
|
|
||||||
wfmDenoiseBtn.textContent = on ? "On" : "Off";
|
|
||||||
wfmDenoiseBtn.style.borderColor = on ? "" : "var(--accent-warn, #f0a500)";
|
|
||||||
wfmDenoiseBtn.style.color = on ? "" : "var(--accent-warn, #f0a500)";
|
|
||||||
}
|
|
||||||
if (wfmStFlagEl && typeof update.filter.wfm_stereo_detected === "boolean") {
|
if (wfmStFlagEl && typeof update.filter.wfm_stereo_detected === "boolean") {
|
||||||
const detected = update.filter.wfm_stereo_detected;
|
const detected = update.filter.wfm_stereo_detected;
|
||||||
wfmStFlagEl.textContent = detected ? "ST" : "MO";
|
wfmStFlagEl.textContent = detected ? "ST" : "MO";
|
||||||
@@ -2566,7 +2560,6 @@ const wfmControlsCol = document.getElementById("wfm-controls-col");
|
|||||||
const wfmDeemphasisEl = document.getElementById("wfm-deemphasis");
|
const wfmDeemphasisEl = document.getElementById("wfm-deemphasis");
|
||||||
const wfmAudioModeEl = document.getElementById("wfm-audio-mode");
|
const wfmAudioModeEl = document.getElementById("wfm-audio-mode");
|
||||||
const wfmStFlagEl = document.getElementById("wfm-st-flag");
|
const wfmStFlagEl = document.getElementById("wfm-st-flag");
|
||||||
const wfmDenoiseBtn = document.getElementById("wfm-denoise-btn");
|
|
||||||
|
|
||||||
// Hide audio row if audio is not configured on the server
|
// Hide audio row if audio is not configured on the server
|
||||||
fetch("/audio", { method: "GET" }).then((r) => {
|
fetch("/audio", { method: "GET" }).then((r) => {
|
||||||
@@ -2610,12 +2603,6 @@ if (wfmDeemphasisEl) {
|
|||||||
postPath(`/set_wfm_deemphasis?us=${encodeURIComponent(wfmDeemphasisEl.value)}`).catch(() => {});
|
postPath(`/set_wfm_deemphasis?us=${encodeURIComponent(wfmDeemphasisEl.value)}`).catch(() => {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (wfmDenoiseBtn) {
|
|
||||||
wfmDenoiseBtn.addEventListener("click", () => {
|
|
||||||
postPath("/toggle_wfm_denoise").catch(() => {});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateWfmControls() {
|
function updateWfmControls() {
|
||||||
if (!wfmControlsCol) return;
|
if (!wfmControlsCol) return;
|
||||||
const mode = (modeEl && modeEl.value ? modeEl.value : "").toUpperCase();
|
const mode = (modeEl && modeEl.value ? modeEl.value : "").toUpperCase();
|
||||||
|
|||||||
@@ -168,9 +168,6 @@
|
|||||||
<label class="wfm-control wfm-st-flag-wrap" aria-label="Stereo pilot status">
|
<label class="wfm-control wfm-st-flag-wrap" aria-label="Stereo pilot status">
|
||||||
<span id="wfm-st-flag" class="wfm-st-flag wfm-st-flag-mono">MO</span>
|
<span id="wfm-st-flag" class="wfm-st-flag wfm-st-flag-mono">MO</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="wfm-control">Denoise
|
|
||||||
<button id="wfm-denoise-btn" type="button" class="status-input toggle-btn toggle-on">On</button>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="label"><span>WFM</span></div>
|
<div class="label"><span>WFM</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -499,21 +499,6 @@ pub async fn set_wfm_stereo(
|
|||||||
send_command(&rig_tx, RigCommand::SetWfmStereo(query.enabled)).await
|
send_command(&rig_tx, RigCommand::SetWfmStereo(query.enabled)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/toggle_wfm_denoise")]
|
|
||||||
pub async fn toggle_wfm_denoise(
|
|
||||||
state: web::Data<watch::Receiver<RigState>>,
|
|
||||||
rig_tx: web::Data<mpsc::Sender<RigRequest>>,
|
|
||||||
) -> Result<HttpResponse, Error> {
|
|
||||||
let enabled = state
|
|
||||||
.get_ref()
|
|
||||||
.borrow()
|
|
||||||
.filter
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.wfm_denoise)
|
|
||||||
.unwrap_or(true);
|
|
||||||
send_command(&rig_tx, RigCommand::SetWfmDenoise(!enabled)).await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/toggle_aprs_decode")]
|
#[post("/toggle_aprs_decode")]
|
||||||
pub async fn toggle_aprs_decode(
|
pub async fn toggle_aprs_decode(
|
||||||
state: web::Data<watch::Receiver<RigState>>,
|
state: web::Data<watch::Receiver<RigState>>,
|
||||||
@@ -727,7 +712,6 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
|||||||
.service(set_fir_taps)
|
.service(set_fir_taps)
|
||||||
.service(set_wfm_deemphasis)
|
.service(set_wfm_deemphasis)
|
||||||
.service(set_wfm_stereo)
|
.service(set_wfm_stereo)
|
||||||
.service(toggle_wfm_denoise)
|
|
||||||
.service(toggle_aprs_decode)
|
.service(toggle_aprs_decode)
|
||||||
.service(toggle_cw_decode)
|
.service(toggle_cw_decode)
|
||||||
.service(set_cw_auto)
|
.service(set_cw_auto)
|
||||||
|
|||||||
@@ -35,6 +35,5 @@ pub enum RigCommand {
|
|||||||
SetFirTaps(u32),
|
SetFirTaps(u32),
|
||||||
SetWfmDeemphasis(u32),
|
SetWfmDeemphasis(u32),
|
||||||
SetWfmStereo(bool),
|
SetWfmStereo(bool),
|
||||||
SetWfmDenoise(bool),
|
|
||||||
GetSpectrum,
|
GetSpectrum,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -518,7 +518,6 @@ pub fn command_from_rig_command(cmd: RigCommand) -> Box<dyn RigCommandHandler> {
|
|||||||
| RigCommand::SetFirTaps(_)
|
| RigCommand::SetFirTaps(_)
|
||||||
| RigCommand::SetWfmDeemphasis(_)
|
| RigCommand::SetWfmDeemphasis(_)
|
||||||
| RigCommand::SetWfmStereo(_)
|
| RigCommand::SetWfmStereo(_)
|
||||||
| RigCommand::SetWfmDenoise(_)
|
|
||||||
| RigCommand::GetSpectrum => Box::new(GetSnapshotCommand),
|
| RigCommand::GetSpectrum => Box::new(GetSnapshotCommand),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,16 +165,6 @@ pub trait RigCat: Rig + Send {
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_wfm_denoise<'a>(
|
|
||||||
&'a mut self,
|
|
||||||
_enabled: bool,
|
|
||||||
) -> Pin<Box<dyn Future<Output = DynResult<()>> + Send + 'a>> {
|
|
||||||
Box::pin(std::future::ready(Err(
|
|
||||||
Box::new(response::RigError::not_supported("set_wfm_denoise"))
|
|
||||||
as Box<dyn std::error::Error + Send + Sync>,
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_wfm_stereo<'a>(
|
fn set_wfm_stereo<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
_enabled: bool,
|
_enabled: bool,
|
||||||
|
|||||||
@@ -273,8 +273,6 @@ pub struct RigFilterState {
|
|||||||
pub wfm_deemphasis_us: u32,
|
pub wfm_deemphasis_us: u32,
|
||||||
#[serde(default = "default_wfm_stereo")]
|
#[serde(default = "default_wfm_stereo")]
|
||||||
pub wfm_stereo: bool,
|
pub wfm_stereo: bool,
|
||||||
#[serde(default = "default_wfm_denoise")]
|
|
||||||
pub wfm_denoise: bool,
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub wfm_stereo_detected: bool,
|
pub wfm_stereo_detected: bool,
|
||||||
}
|
}
|
||||||
@@ -283,10 +281,6 @@ fn default_wfm_deemphasis_us() -> u32 {
|
|||||||
75
|
75
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_wfm_denoise() -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_wfm_stereo() -> bool {
|
fn default_wfm_stereo() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,7 +299,6 @@ mod tests {
|
|||||||
cw_center_hz: 700,
|
cw_center_hz: 700,
|
||||||
wfm_deemphasis_us: 75,
|
wfm_deemphasis_us: 75,
|
||||||
wfm_stereo: true,
|
wfm_stereo: true,
|
||||||
wfm_denoise: true,
|
|
||||||
wfm_stereo_detected: false,
|
wfm_stereo_detected: false,
|
||||||
}),
|
}),
|
||||||
..minimal_snapshot()
|
..minimal_snapshot()
|
||||||
@@ -338,7 +337,6 @@ mod tests {
|
|||||||
cw_center_hz: 700,
|
cw_center_hz: 700,
|
||||||
wfm_deemphasis_us: 50,
|
wfm_deemphasis_us: 50,
|
||||||
wfm_stereo: true,
|
wfm_stereo: true,
|
||||||
wfm_denoise: true,
|
|
||||||
wfm_stereo_detected: true,
|
wfm_stereo_detected: true,
|
||||||
}),
|
}),
|
||||||
..minimal_snapshot()
|
..minimal_snapshot()
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ pub fn client_command_to_rig(cmd: ClientCommand) -> RigCommand {
|
|||||||
RigCommand::SetWfmDeemphasis(deemphasis_us)
|
RigCommand::SetWfmDeemphasis(deemphasis_us)
|
||||||
}
|
}
|
||||||
ClientCommand::SetWfmStereo { enabled } => RigCommand::SetWfmStereo(enabled),
|
ClientCommand::SetWfmStereo { enabled } => RigCommand::SetWfmStereo(enabled),
|
||||||
ClientCommand::SetWfmDenoise { enabled } => RigCommand::SetWfmDenoise(enabled),
|
|
||||||
ClientCommand::GetSpectrum => RigCommand::GetSpectrum,
|
ClientCommand::GetSpectrum => RigCommand::GetSpectrum,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +97,6 @@ pub fn rig_command_to_client(cmd: RigCommand) -> ClientCommand {
|
|||||||
ClientCommand::SetWfmDeemphasis { deemphasis_us }
|
ClientCommand::SetWfmDeemphasis { deemphasis_us }
|
||||||
}
|
}
|
||||||
RigCommand::SetWfmStereo(enabled) => ClientCommand::SetWfmStereo { enabled },
|
RigCommand::SetWfmStereo(enabled) => ClientCommand::SetWfmStereo { enabled },
|
||||||
RigCommand::SetWfmDenoise(enabled) => ClientCommand::SetWfmDenoise { enabled },
|
|
||||||
RigCommand::GetSpectrum => ClientCommand::GetSpectrum,
|
RigCommand::GetSpectrum => ClientCommand::GetSpectrum,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ pub enum ClientCommand {
|
|||||||
SetFirTaps { taps: u32 },
|
SetFirTaps { taps: u32 },
|
||||||
SetWfmDeemphasis { deemphasis_us: u32 },
|
SetWfmDeemphasis { deemphasis_us: u32 },
|
||||||
SetWfmStereo { enabled: bool },
|
SetWfmStereo { enabled: bool },
|
||||||
SetWfmDenoise { enabled: bool },
|
|
||||||
GetSpectrum,
|
GetSpectrum,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ impl Default for AudioConfig {
|
|||||||
tx_enabled: true,
|
tx_enabled: true,
|
||||||
device: None,
|
device: None,
|
||||||
sample_rate: 48000,
|
sample_rate: 48000,
|
||||||
channels: 1,
|
channels: 2,
|
||||||
frame_duration_ms: 20,
|
frame_duration_ms: 20,
|
||||||
bitrate_bps: 192000,
|
bitrate_bps: 192000,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -472,16 +472,6 @@ async fn process_command(
|
|||||||
let _ = ctx.state_tx.send(ctx.state.clone());
|
let _ = ctx.state_tx.send(ctx.state.clone());
|
||||||
return snapshot_from(ctx.state);
|
return snapshot_from(ctx.state);
|
||||||
}
|
}
|
||||||
RigCommand::SetWfmDenoise(enabled) => {
|
|
||||||
if let Err(e) = ctx.rig.set_wfm_denoise(enabled).await {
|
|
||||||
return Err(RigError::communication(format!("set_wfm_denoise: {e}")));
|
|
||||||
}
|
|
||||||
if let Some(f) = ctx.state.filter.as_mut() {
|
|
||||||
f.wfm_denoise = enabled;
|
|
||||||
}
|
|
||||||
let _ = ctx.state_tx.send(ctx.state.clone());
|
|
||||||
return snapshot_from(ctx.state);
|
|
||||||
}
|
|
||||||
RigCommand::SetCenterFreq(freq) => {
|
RigCommand::SetCenterFreq(freq) => {
|
||||||
if let Err(e) = ctx.rig.set_center_freq(freq).await {
|
if let Err(e) = ctx.rig.set_center_freq(freq).await {
|
||||||
return Err(RigError::communication(format!("set_center_freq: {e}")));
|
return Err(RigError::communication(format!("set_center_freq: {e}")));
|
||||||
|
|||||||
@@ -297,52 +297,6 @@ impl BiquadNotch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Three-band stereo blend for WFM.
|
|
||||||
///
|
|
||||||
/// Splits the L-R diff signal into three bands at audio rate and applies
|
|
||||||
/// SNR-dependent blending per band. Weaker pilot → more aggressive noise
|
|
||||||
/// reduction at higher frequencies while low frequencies retain more stereo.
|
|
||||||
///
|
|
||||||
/// | Band | Frequency | Blend factor |
|
|
||||||
/// |-----------|-------------|--------------|
|
|
||||||
/// | Low | 0 – 2 kHz | `blend` |
|
|
||||||
/// | Mid | 2 – 8 kHz | `blend²` |
|
|
||||||
/// | High | 8 – 15 kHz | `blend⁴` |
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
struct MultibandStereoBlend {
|
|
||||||
/// 2nd-order Butterworth LPF at the low/mid crossover (2 kHz).
|
|
||||||
lo_lp: BiquadLowPass,
|
|
||||||
/// 2nd-order Butterworth LPF at the mid/high crossover (8 kHz).
|
|
||||||
hi_lp: BiquadLowPass,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MultibandStereoBlend {
|
|
||||||
fn new(audio_rate: f32) -> Self {
|
|
||||||
// Q = 1/√2 ≈ 0.7071 — maximally flat (Butterworth) 2nd-order response.
|
|
||||||
let q = std::f32::consts::FRAC_1_SQRT_2;
|
|
||||||
Self {
|
|
||||||
lo_lp: BiquadLowPass::new(audio_rate, 2_000.0, q),
|
|
||||||
hi_lp: BiquadLowPass::new(audio_rate, 8_000.0, q),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Apply multiband blend to a single diff sample.
|
|
||||||
///
|
|
||||||
/// `blend` is the pilot SNR estimate in [0, 1] (0 = mono, 1 = full stereo).
|
|
||||||
fn process(&mut self, diff: f32, blend: f32) -> f32 {
|
|
||||||
// Band-split via complementary LPFs.
|
|
||||||
let lo = self.lo_lp.process(diff); // 0 – 2 kHz
|
|
||||||
let lo_hi = self.hi_lp.process(diff); // 0 – 8 kHz
|
|
||||||
let mid = lo_hi - lo; // 2 – 8 kHz
|
|
||||||
let hi = diff - lo_hi; // 8 – 15 kHz
|
|
||||||
|
|
||||||
let blend2 = blend * blend;
|
|
||||||
let blend4 = blend2 * blend2;
|
|
||||||
|
|
||||||
lo * blend + mid * blend2 + hi * blend4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OnePoleLowPass {
|
impl OnePoleLowPass {
|
||||||
fn new(sample_rate: f32, cutoff_hz: f32) -> Self {
|
fn new(sample_rate: f32, cutoff_hz: f32) -> Self {
|
||||||
let sr = sample_rate.max(1.0);
|
let sr = sample_rate.max(1.0);
|
||||||
@@ -414,10 +368,6 @@ pub struct WfmStereoDecoder {
|
|||||||
deemph_m: Deemphasis,
|
deemph_m: Deemphasis,
|
||||||
deemph_l: Deemphasis,
|
deemph_l: Deemphasis,
|
||||||
deemph_r: Deemphasis,
|
deemph_r: Deemphasis,
|
||||||
/// Multiband stereo blending applied at audio rate to the L-R diff channel.
|
|
||||||
diff_denoise: MultibandStereoBlend,
|
|
||||||
/// Whether multiband stereo denoising is active.
|
|
||||||
denoise_enabled: bool,
|
|
||||||
/// Smoothed pilot-derived stereo detection strength in [0, 1].
|
/// Smoothed pilot-derived stereo detection strength in [0, 1].
|
||||||
stereo_detect_level: f32,
|
stereo_detect_level: f32,
|
||||||
/// Hysteretic pilot-lock result used by the UI.
|
/// Hysteretic pilot-lock result used by the UI.
|
||||||
@@ -453,7 +403,6 @@ impl WfmStereoDecoder {
|
|||||||
output_channels: usize,
|
output_channels: usize,
|
||||||
stereo_enabled: bool,
|
stereo_enabled: bool,
|
||||||
deemphasis_us: u32,
|
deemphasis_us: u32,
|
||||||
denoise_enabled: bool,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let composite_rate_f = composite_rate.max(1) as f32;
|
let composite_rate_f = composite_rate.max(1) as f32;
|
||||||
let output_phase_inc = audio_rate.max(1) as f64 / composite_rate.max(1) as f64;
|
let output_phase_inc = audio_rate.max(1) as f64 / composite_rate.max(1) as f64;
|
||||||
@@ -487,8 +436,6 @@ impl WfmStereoDecoder {
|
|||||||
deemph_m: Deemphasis::new(audio_rate.max(1) as f32, deemphasis_us),
|
deemph_m: Deemphasis::new(audio_rate.max(1) as f32, deemphasis_us),
|
||||||
deemph_l: Deemphasis::new(audio_rate.max(1) as f32, deemphasis_us),
|
deemph_l: Deemphasis::new(audio_rate.max(1) as f32, deemphasis_us),
|
||||||
deemph_r: Deemphasis::new(audio_rate.max(1) as f32, deemphasis_us),
|
deemph_r: Deemphasis::new(audio_rate.max(1) as f32, deemphasis_us),
|
||||||
diff_denoise: MultibandStereoBlend::new(audio_rate.max(1) as f32),
|
|
||||||
denoise_enabled,
|
|
||||||
stereo_detect_level: 0.0,
|
stereo_detect_level: 0.0,
|
||||||
stereo_detected: false,
|
stereo_detected: false,
|
||||||
fm_gain: composite_rate_f / (2.0 * 75_000.0),
|
fm_gain: composite_rate_f / (2.0 * 75_000.0),
|
||||||
@@ -601,17 +548,9 @@ impl WfmStereoDecoder {
|
|||||||
|
|
||||||
// --- Deemphasis + DC block + output ---
|
// --- Deemphasis + DC block + output ---
|
||||||
if self.output_channels >= 2 && self.stereo_enabled {
|
if self.output_channels >= 2 && self.stereo_enabled {
|
||||||
// Apply multiband or single-band stereo blend at audio rate.
|
let diff = diff_i * blend_i;
|
||||||
let diff_denoised = if self.denoise_enabled {
|
let left_corr = (sum_i + diff) * 0.5;
|
||||||
// Multiband: attenuates high-frequency diff more aggressively
|
let right_corr = (sum_i - diff) * 0.5;
|
||||||
// when the pilot is weak, preserving the low-frequency stereo image.
|
|
||||||
self.diff_denoise.process(diff_i, blend_i)
|
|
||||||
} else {
|
|
||||||
// Single-band: uniform blend across all frequencies.
|
|
||||||
diff_i * blend_i
|
|
||||||
};
|
|
||||||
let left_corr = (sum_i + diff_denoised) * 0.5;
|
|
||||||
let right_corr = (sum_i - diff_denoised) * 0.5;
|
|
||||||
let left = self
|
let left = self
|
||||||
.dc_l
|
.dc_l
|
||||||
.process(self.pilot_notch_l.process(self.deemph_l.process(left_corr)))
|
.process(self.pilot_notch_l.process(self.deemph_l.process(left_corr)))
|
||||||
@@ -640,10 +579,6 @@ impl WfmStereoDecoder {
|
|||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_denoise_enabled(&mut self, enabled: bool) {
|
|
||||||
self.denoise_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_stereo_enabled(&mut self, enabled: bool) {
|
pub fn set_stereo_enabled(&mut self, enabled: bool) {
|
||||||
self.stereo_enabled = enabled;
|
self.stereo_enabled = enabled;
|
||||||
}
|
}
|
||||||
@@ -987,7 +922,6 @@ mod tests {
|
|||||||
2, // stereo output
|
2, // stereo output
|
||||||
true, // stereo enabled
|
true, // stereo enabled
|
||||||
50, // 50 µs deemphasis
|
50, // 50 µs deemphasis
|
||||||
false, // no denoise — test raw separation
|
|
||||||
);
|
);
|
||||||
let output = decoder.process_iq(&iq);
|
let output = decoder.process_iq(&iq);
|
||||||
|
|
||||||
@@ -1069,7 +1003,6 @@ mod tests {
|
|||||||
2,
|
2,
|
||||||
true,
|
true,
|
||||||
50,
|
50,
|
||||||
false,
|
|
||||||
);
|
);
|
||||||
let output = decoder.process_iq(&iq);
|
let output = decoder.process_iq(&iq);
|
||||||
|
|
||||||
|
|||||||
@@ -311,8 +311,6 @@ pub struct ChannelDsp {
|
|||||||
wfm_deemphasis_us: u32,
|
wfm_deemphasis_us: u32,
|
||||||
/// Whether WFM stereo decoding is enabled.
|
/// Whether WFM stereo decoding is enabled.
|
||||||
wfm_stereo: bool,
|
wfm_stereo: bool,
|
||||||
/// Whether multiband stereo denoising is enabled for WFM.
|
|
||||||
wfm_denoise: bool,
|
|
||||||
/// Decimation factor: `sdr_sample_rate / audio_sample_rate`.
|
/// Decimation factor: `sdr_sample_rate / audio_sample_rate`.
|
||||||
pub decim_factor: usize,
|
pub decim_factor: usize,
|
||||||
/// Number of PCM channels emitted in each frame.
|
/// Number of PCM channels emitted in each frame.
|
||||||
@@ -414,7 +412,6 @@ impl ChannelDsp {
|
|||||||
self.output_channels,
|
self.output_channels,
|
||||||
self.wfm_stereo,
|
self.wfm_stereo,
|
||||||
self.wfm_deemphasis_us,
|
self.wfm_deemphasis_us,
|
||||||
self.wfm_denoise,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -436,7 +433,6 @@ impl ChannelDsp {
|
|||||||
audio_bandwidth_hz: u32,
|
audio_bandwidth_hz: u32,
|
||||||
wfm_deemphasis_us: u32,
|
wfm_deemphasis_us: u32,
|
||||||
wfm_stereo: bool,
|
wfm_stereo: bool,
|
||||||
wfm_denoise: bool,
|
|
||||||
fir_taps: usize,
|
fir_taps: usize,
|
||||||
pcm_tx: broadcast::Sender<Vec<f32>>,
|
pcm_tx: broadcast::Sender<Vec<f32>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -482,7 +478,6 @@ impl ChannelDsp {
|
|||||||
fir_taps: taps,
|
fir_taps: taps,
|
||||||
wfm_deemphasis_us,
|
wfm_deemphasis_us,
|
||||||
wfm_stereo,
|
wfm_stereo,
|
||||||
wfm_denoise,
|
|
||||||
decim_factor,
|
decim_factor,
|
||||||
output_channels,
|
output_channels,
|
||||||
frame_buf: Vec::with_capacity(frame_size + output_channels),
|
frame_buf: Vec::with_capacity(frame_size + output_channels),
|
||||||
@@ -504,7 +499,6 @@ impl ChannelDsp {
|
|||||||
output_channels,
|
output_channels,
|
||||||
wfm_stereo,
|
wfm_stereo,
|
||||||
wfm_deemphasis_us,
|
wfm_deemphasis_us,
|
||||||
wfm_denoise,
|
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -557,13 +551,6 @@ impl ChannelDsp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_wfm_denoise(&mut self, enabled: bool) {
|
|
||||||
self.wfm_denoise = enabled;
|
|
||||||
if let Some(decoder) = &mut self.wfm_decoder {
|
|
||||||
decoder.set_denoise_enabled(enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rds_data(&self) -> Option<RdsData> {
|
pub fn rds_data(&self) -> Option<RdsData> {
|
||||||
self.wfm_decoder.as_ref().and_then(WfmStereoDecoder::rds_data)
|
self.wfm_decoder.as_ref().and_then(WfmStereoDecoder::rds_data)
|
||||||
}
|
}
|
||||||
@@ -724,7 +711,6 @@ impl SdrPipeline {
|
|||||||
frame_duration_ms: u16,
|
frame_duration_ms: u16,
|
||||||
wfm_deemphasis_us: u32,
|
wfm_deemphasis_us: u32,
|
||||||
wfm_stereo: bool,
|
wfm_stereo: bool,
|
||||||
wfm_denoise: bool,
|
|
||||||
channels: &[(f64, RigMode, u32, usize)],
|
channels: &[(f64, RigMode, u32, usize)],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
const IQ_BROADCAST_CAPACITY: usize = 64;
|
const IQ_BROADCAST_CAPACITY: usize = 64;
|
||||||
@@ -747,7 +733,6 @@ impl SdrPipeline {
|
|||||||
audio_bandwidth_hz,
|
audio_bandwidth_hz,
|
||||||
wfm_deemphasis_us,
|
wfm_deemphasis_us,
|
||||||
wfm_stereo,
|
wfm_stereo,
|
||||||
wfm_denoise,
|
|
||||||
fir_taps,
|
fir_taps,
|
||||||
pcm_tx.clone(),
|
pcm_tx.clone(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ pub struct SoapySdrRig {
|
|||||||
wfm_deemphasis_us: u32,
|
wfm_deemphasis_us: u32,
|
||||||
/// Whether WFM stereo decode is enabled.
|
/// Whether WFM stereo decode is enabled.
|
||||||
wfm_stereo: bool,
|
wfm_stereo: bool,
|
||||||
/// Whether multiband WFM stereo denoising is enabled.
|
|
||||||
wfm_denoise: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoapySdrRig {
|
impl SoapySdrRig {
|
||||||
@@ -120,7 +118,6 @@ impl SoapySdrRig {
|
|||||||
frame_duration_ms,
|
frame_duration_ms,
|
||||||
wfm_deemphasis_us,
|
wfm_deemphasis_us,
|
||||||
true, // wfm_stereo: enabled by default
|
true, // wfm_stereo: enabled by default
|
||||||
true, // wfm_denoise: enabled by default
|
|
||||||
channels,
|
channels,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -189,7 +186,6 @@ impl SoapySdrRig {
|
|||||||
retune_cmd,
|
retune_cmd,
|
||||||
wfm_deemphasis_us,
|
wfm_deemphasis_us,
|
||||||
wfm_stereo: true,
|
wfm_stereo: true,
|
||||||
wfm_denoise: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,19 +477,6 @@ impl RigCat for SoapySdrRig {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_wfm_denoise<'a>(
|
|
||||||
&'a mut self,
|
|
||||||
enabled: bool,
|
|
||||||
) -> Pin<Box<dyn std::future::Future<Output = DynResult<()>> + Send + 'a>> {
|
|
||||||
Box::pin(async move {
|
|
||||||
self.wfm_denoise = enabled;
|
|
||||||
if let Some(dsp_arc) = self.pipeline.channel_dsps.get(self.primary_channel_idx) {
|
|
||||||
dsp_arc.lock().unwrap().set_wfm_denoise(enabled);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn filter_state(&self) -> Option<RigFilterState> {
|
fn filter_state(&self) -> Option<RigFilterState> {
|
||||||
let wfm_stereo_detected = self
|
let wfm_stereo_detected = self
|
||||||
.pipeline
|
.pipeline
|
||||||
@@ -507,7 +490,6 @@ impl RigCat for SoapySdrRig {
|
|||||||
cw_center_hz: 700,
|
cw_center_hz: 700,
|
||||||
wfm_deemphasis_us: self.wfm_deemphasis_us,
|
wfm_deemphasis_us: self.wfm_deemphasis_us,
|
||||||
wfm_stereo: self.wfm_stereo,
|
wfm_stereo: self.wfm_stereo,
|
||||||
wfm_denoise: self.wfm_denoise,
|
|
||||||
wfm_stereo_detected,
|
wfm_stereo_detected,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user