mirror of
https://github.com/smittix/intercept.git
synced 2026-07-31 11:53:05 -07:00
Snapshot audio tune config when spawning demod process
This commit is contained in:
+76
-52
@@ -665,25 +665,41 @@ def scanner_loop_power():
|
|||||||
logger.info("Power sweep scanner thread stopped")
|
logger.info("Power sweep scanner thread stopped")
|
||||||
|
|
||||||
|
|
||||||
def _start_audio_stream(frequency: float, modulation: str):
|
def _start_audio_stream(
|
||||||
"""Start audio streaming at given frequency."""
|
frequency: float,
|
||||||
global audio_process, audio_rtl_process, audio_running, audio_frequency, audio_modulation
|
modulation: str,
|
||||||
|
*,
|
||||||
with audio_lock:
|
device: int | None = None,
|
||||||
# Stop any existing stream
|
sdr_type: str | None = None,
|
||||||
_stop_audio_stream_internal()
|
gain: int | None = None,
|
||||||
|
squelch: int | None = None,
|
||||||
|
bias_t: bool | None = None,
|
||||||
|
):
|
||||||
|
"""Start audio streaming at given frequency."""
|
||||||
|
global audio_process, audio_rtl_process, audio_running, audio_frequency, audio_modulation
|
||||||
|
|
||||||
|
with audio_lock:
|
||||||
|
# Stop any existing stream
|
||||||
|
_stop_audio_stream_internal()
|
||||||
|
|
||||||
ffmpeg_path = find_ffmpeg()
|
ffmpeg_path = find_ffmpeg()
|
||||||
if not ffmpeg_path:
|
if not ffmpeg_path:
|
||||||
logger.error("ffmpeg not found")
|
logger.error("ffmpeg not found")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Determine SDR type and build appropriate command
|
# Snapshot runtime tuning config so the spawned demod command cannot
|
||||||
sdr_type_str = scanner_config.get('sdr_type', 'rtlsdr')
|
# drift if shared scanner_config changes while startup is in-flight.
|
||||||
try:
|
device_index = int(device if device is not None else scanner_config.get('device', 0))
|
||||||
sdr_type = SDRType(sdr_type_str)
|
gain_value = int(gain if gain is not None else scanner_config.get('gain', 40))
|
||||||
except ValueError:
|
squelch_value = int(squelch if squelch is not None else scanner_config.get('squelch', 0))
|
||||||
sdr_type = SDRType.RTL_SDR
|
bias_t_enabled = bool(scanner_config.get('bias_t', False) if bias_t is None else bias_t)
|
||||||
|
sdr_type_str = str(sdr_type if sdr_type is not None else scanner_config.get('sdr_type', 'rtlsdr')).lower()
|
||||||
|
|
||||||
|
# Determine SDR type and build appropriate command
|
||||||
|
try:
|
||||||
|
sdr_type = SDRType(sdr_type_str)
|
||||||
|
except ValueError:
|
||||||
|
sdr_type = SDRType.RTL_SDR
|
||||||
|
|
||||||
# Set sample rates based on modulation
|
# Set sample rates based on modulation
|
||||||
if modulation == 'wfm':
|
if modulation == 'wfm':
|
||||||
@@ -707,41 +723,41 @@ def _start_audio_stream(frequency: float, modulation: str):
|
|||||||
freq_hz = int(frequency * 1e6)
|
freq_hz = int(frequency * 1e6)
|
||||||
sdr_cmd = [
|
sdr_cmd = [
|
||||||
rtl_fm_path,
|
rtl_fm_path,
|
||||||
'-M', _rtl_fm_demod_mode(modulation),
|
'-M', _rtl_fm_demod_mode(modulation),
|
||||||
'-f', str(freq_hz),
|
'-f', str(freq_hz),
|
||||||
'-s', str(sample_rate),
|
'-s', str(sample_rate),
|
||||||
'-r', str(resample_rate),
|
'-r', str(resample_rate),
|
||||||
'-g', str(scanner_config['gain']),
|
'-g', str(gain_value),
|
||||||
'-d', str(scanner_config['device']),
|
'-d', str(device_index),
|
||||||
'-l', str(scanner_config['squelch']),
|
'-l', str(squelch_value),
|
||||||
]
|
]
|
||||||
if scanner_config.get('bias_t', False):
|
if bias_t_enabled:
|
||||||
sdr_cmd.append('-T')
|
sdr_cmd.append('-T')
|
||||||
# Omit explicit filename: rtl_fm defaults to stdout.
|
# Omit explicit filename: rtl_fm defaults to stdout.
|
||||||
# (Some builds intermittently stall when '-' is passed explicitly.)
|
# (Some builds intermittently stall when '-' is passed explicitly.)
|
||||||
else:
|
else:
|
||||||
# Use SDR abstraction layer for HackRF, Airspy, LimeSDR, SDRPlay
|
# Use SDR abstraction layer for HackRF, Airspy, LimeSDR, SDRPlay
|
||||||
rx_fm_path = find_rx_fm()
|
rx_fm_path = find_rx_fm()
|
||||||
if not rx_fm_path:
|
if not rx_fm_path:
|
||||||
logger.error(f"rx_fm not found - required for {sdr_type.value}. Install SoapySDR utilities.")
|
logger.error(f"rx_fm not found - required for {sdr_type.value}. Install SoapySDR utilities.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create device and get command builder
|
# Create device and get command builder
|
||||||
device = SDRFactory.create_default_device(sdr_type, index=scanner_config['device'])
|
sdr_device = SDRFactory.create_default_device(sdr_type, index=device_index)
|
||||||
builder = SDRFactory.get_builder(sdr_type)
|
builder = SDRFactory.get_builder(sdr_type)
|
||||||
|
|
||||||
# Build FM demod command
|
# Build FM demod command
|
||||||
sdr_cmd = builder.build_fm_demod_command(
|
sdr_cmd = builder.build_fm_demod_command(
|
||||||
device=device,
|
device=sdr_device,
|
||||||
frequency_mhz=frequency,
|
frequency_mhz=frequency,
|
||||||
sample_rate=resample_rate,
|
sample_rate=resample_rate,
|
||||||
gain=float(scanner_config['gain']),
|
gain=float(gain_value),
|
||||||
modulation=modulation,
|
modulation=modulation,
|
||||||
squelch=scanner_config['squelch'],
|
squelch=squelch_value,
|
||||||
bias_t=scanner_config.get('bias_t', False)
|
bias_t=bias_t_enabled,
|
||||||
)
|
)
|
||||||
# Ensure we use the found rx_fm path
|
# Ensure we use the found rx_fm path
|
||||||
sdr_cmd[0] = rx_fm_path
|
sdr_cmd[0] = rx_fm_path
|
||||||
|
|
||||||
encoder_cmd = [
|
encoder_cmd = [
|
||||||
ffmpeg_path,
|
ffmpeg_path,
|
||||||
@@ -762,11 +778,11 @@ def _start_audio_stream(frequency: float, modulation: str):
|
|||||||
]
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Use subprocess piping for reliable streaming.
|
# Use subprocess piping for reliable streaming.
|
||||||
# Log stderr to temp files for error diagnosis.
|
# Log stderr to temp files for error diagnosis.
|
||||||
rtl_stderr_log = '/tmp/rtl_fm_stderr.log'
|
rtl_stderr_log = '/tmp/rtl_fm_stderr.log'
|
||||||
ffmpeg_stderr_log = '/tmp/ffmpeg_stderr.log'
|
ffmpeg_stderr_log = '/tmp/ffmpeg_stderr.log'
|
||||||
logger.info(f"Starting audio: {frequency} MHz, mod={modulation}, device={scanner_config['device']}")
|
logger.info(f"Starting audio: {frequency} MHz, mod={modulation}, device={device_index}")
|
||||||
|
|
||||||
# Retry loop for USB device contention (device may not be
|
# Retry loop for USB device contention (device may not be
|
||||||
# released immediately after a previous process exits)
|
# released immediately after a previous process exits)
|
||||||
@@ -1432,7 +1448,15 @@ def start_audio() -> Response:
|
|||||||
}), 409
|
}), 409
|
||||||
receiver_active_device = device
|
receiver_active_device = device
|
||||||
|
|
||||||
_start_audio_stream(frequency, modulation)
|
_start_audio_stream(
|
||||||
|
frequency,
|
||||||
|
modulation,
|
||||||
|
device=device,
|
||||||
|
sdr_type=sdr_type,
|
||||||
|
gain=gain,
|
||||||
|
squelch=squelch,
|
||||||
|
bias_t=bias_t,
|
||||||
|
)
|
||||||
|
|
||||||
if audio_running:
|
if audio_running:
|
||||||
audio_source = 'process'
|
audio_source = 'process'
|
||||||
|
|||||||
Reference in New Issue
Block a user