[feat](trx-backend-soapysdr): enable hardware AGC by default if available
Query the device for AGC support via has_gain_mode and enable it automatically at startup. Devices without hardware AGC fall back to manual gain as before. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
@@ -69,6 +69,11 @@ pub trait IqSource: Send + 'static {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns `true` when the hardware supports automatic gain control.
|
||||
fn has_gain_mode(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Enable or disable hardware automatic gain control. Default
|
||||
/// implementation is a no-op for sources that do not support AGC.
|
||||
fn set_gain_mode(&mut self, _automatic: bool) -> Result<(), String> {
|
||||
|
||||
@@ -92,8 +92,6 @@ impl SoapySdrRig {
|
||||
/// - `gain_mode`: `"auto"` or `"manual"`.
|
||||
/// - `gain_db`: gain in dB; used when `gain_mode == "manual"`.
|
||||
/// - `max_gain_db`: optional hard ceiling for the applied hardware gain.
|
||||
/// When `gain_mode == "auto"` hardware AGC is not yet wired, so this
|
||||
/// value acts as the fallback.
|
||||
/// - `audio_sample_rate`: output PCM rate (Hz).
|
||||
/// - `frame_duration_ms`: output frame length (ms).
|
||||
/// - `initial_freq`: initial dial frequency reported by `get_status`.
|
||||
@@ -137,8 +135,6 @@ impl SoapySdrRig {
|
||||
max_gain_db,
|
||||
);
|
||||
|
||||
let agc_enabled = gain_mode == "auto";
|
||||
|
||||
let effective_gain_db = max_gain_db
|
||||
.map(|max_gain| gain_db.min(max_gain))
|
||||
.unwrap_or(gain_db);
|
||||
@@ -155,7 +151,7 @@ impl SoapySdrRig {
|
||||
let hardware_center_hz = initial_freq.hz as i64 - center_offset_hz;
|
||||
|
||||
// Create real IQ source from hardware device.
|
||||
let iq_source = real_iq_source::RealIqSource::new(
|
||||
let mut iq_source = real_iq_source::RealIqSource::new(
|
||||
args,
|
||||
hardware_center_hz as f64,
|
||||
sdr_sample_rate as f64,
|
||||
@@ -169,6 +165,23 @@ impl SoapySdrRig {
|
||||
if let Some(lna) = initial_lna_gain_db {
|
||||
tracing::info!("SDR LNA gain element present, initial value: {:.1} dB", lna);
|
||||
}
|
||||
|
||||
// Enable hardware AGC by default if the device supports it.
|
||||
let agc_enabled = if iq_source.has_gain_mode() {
|
||||
match iq_source.set_gain_mode(true) {
|
||||
Ok(()) => {
|
||||
tracing::info!("Hardware AGC enabled by default");
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!("Failed to enable hardware AGC: {}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tracing::debug!("Hardware AGC not supported by this device");
|
||||
false
|
||||
};
|
||||
let iq_source: Box<dyn dsp::IqSource> = Box::new(iq_source);
|
||||
|
||||
let primary_channel_count = channels.len();
|
||||
|
||||
@@ -191,6 +191,12 @@ impl IqSource for RealIqSource {
|
||||
.ok()
|
||||
}
|
||||
|
||||
fn has_gain_mode(&self) -> bool {
|
||||
self.device
|
||||
.has_gain_mode(soapysdr::Direction::Rx, 0)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn set_gain_mode(&mut self, automatic: bool) -> Result<(), String> {
|
||||
self.device
|
||||
.set_gain_mode(soapysdr::Direction::Rx, 0, automatic)
|
||||
|
||||
Reference in New Issue
Block a user