[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
|
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
|
/// Enable or disable hardware automatic gain control. Default
|
||||||
/// implementation is a no-op for sources that do not support AGC.
|
/// implementation is a no-op for sources that do not support AGC.
|
||||||
fn set_gain_mode(&mut self, _automatic: bool) -> Result<(), String> {
|
fn set_gain_mode(&mut self, _automatic: bool) -> Result<(), String> {
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ impl SoapySdrRig {
|
|||||||
/// - `gain_mode`: `"auto"` or `"manual"`.
|
/// - `gain_mode`: `"auto"` or `"manual"`.
|
||||||
/// - `gain_db`: gain in dB; used when `gain_mode == "manual"`.
|
/// - `gain_db`: gain in dB; used when `gain_mode == "manual"`.
|
||||||
/// - `max_gain_db`: optional hard ceiling for the applied hardware gain.
|
/// - `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).
|
/// - `audio_sample_rate`: output PCM rate (Hz).
|
||||||
/// - `frame_duration_ms`: output frame length (ms).
|
/// - `frame_duration_ms`: output frame length (ms).
|
||||||
/// - `initial_freq`: initial dial frequency reported by `get_status`.
|
/// - `initial_freq`: initial dial frequency reported by `get_status`.
|
||||||
@@ -137,8 +135,6 @@ impl SoapySdrRig {
|
|||||||
max_gain_db,
|
max_gain_db,
|
||||||
);
|
);
|
||||||
|
|
||||||
let agc_enabled = gain_mode == "auto";
|
|
||||||
|
|
||||||
let effective_gain_db = max_gain_db
|
let effective_gain_db = max_gain_db
|
||||||
.map(|max_gain| gain_db.min(max_gain))
|
.map(|max_gain| gain_db.min(max_gain))
|
||||||
.unwrap_or(gain_db);
|
.unwrap_or(gain_db);
|
||||||
@@ -155,7 +151,7 @@ impl SoapySdrRig {
|
|||||||
let hardware_center_hz = initial_freq.hz as i64 - center_offset_hz;
|
let hardware_center_hz = initial_freq.hz as i64 - center_offset_hz;
|
||||||
|
|
||||||
// Create real IQ source from hardware device.
|
// 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,
|
args,
|
||||||
hardware_center_hz as f64,
|
hardware_center_hz as f64,
|
||||||
sdr_sample_rate as f64,
|
sdr_sample_rate as f64,
|
||||||
@@ -169,6 +165,23 @@ impl SoapySdrRig {
|
|||||||
if let Some(lna) = initial_lna_gain_db {
|
if let Some(lna) = initial_lna_gain_db {
|
||||||
tracing::info!("SDR LNA gain element present, initial value: {:.1} dB", lna);
|
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 iq_source: Box<dyn dsp::IqSource> = Box::new(iq_source);
|
||||||
|
|
||||||
let primary_channel_count = channels.len();
|
let primary_channel_count = channels.len();
|
||||||
|
|||||||
@@ -191,6 +191,12 @@ impl IqSource for RealIqSource {
|
|||||||
.ok()
|
.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> {
|
fn set_gain_mode(&mut self, automatic: bool) -> Result<(), String> {
|
||||||
self.device
|
self.device
|
||||||
.set_gain_mode(soapysdr::Direction::Rx, 0, automatic)
|
.set_gain_mode(soapysdr::Direction::Rx, 0, automatic)
|
||||||
|
|||||||
Reference in New Issue
Block a user