This commit is contained in:
awe
2026-03-12 18:09:44 +03:00
parent f02de1c3d0
commit 5054f8d3d7
5 changed files with 144 additions and 29 deletions

View File

@ -17,7 +17,7 @@ class RingBuffer:
def __init__(self, max_sweeps: int):
self.max_sweeps = int(max_sweeps)
self.fft_bins = FFT_LEN // 2 + 1
self.fft_symmetric = True
self.fft_mode = "symmetric"
self.width = 0
self.head = 0
self.ring: Optional[np.ndarray] = None
@ -34,6 +34,10 @@ class RingBuffer:
def is_ready(self) -> bool:
return self.ring is not None and self.ring_fft is not None
@property
def fft_symmetric(self) -> bool:
return self.fft_mode == "symmetric"
def ensure_init(self, sweep_width: int) -> bool:
"""Allocate or resize buffers. Returns True when geometry changed."""
target_width = max(int(sweep_width), int(WF_WIDTH))
@ -63,13 +67,21 @@ class RingBuffer:
changed = True
return changed
def set_symmetric_fft_enabled(self, enabled: bool) -> bool:
def set_fft_mode(self, mode: str) -> bool:
"""Switch FFT mode and rebuild cached FFT rows from stored sweeps."""
enabled_bool = bool(enabled)
if enabled_bool == self.fft_symmetric:
normalized_mode = str(mode).strip().lower()
if normalized_mode in {"ordinary", "normal"}:
normalized_mode = "direct"
if normalized_mode in {"sym", "mirror"}:
normalized_mode = "symmetric"
if normalized_mode in {"positive-centered", "positive_centered", "zero_left"}:
normalized_mode = "positive_only"
if normalized_mode not in {"direct", "symmetric", "positive_only"}:
raise ValueError(f"Unsupported FFT mode: {mode!r}")
if normalized_mode == self.fft_mode:
return False
self.fft_symmetric = enabled_bool
self.fft_mode = normalized_mode
self.y_min_fft = None
self.y_max_fft = None
@ -85,7 +97,7 @@ class RingBuffer:
sweep_row,
self.last_freqs,
self.fft_bins,
symmetric=self.fft_symmetric,
mode=self.fft_mode,
)
self.ring_fft[row_idx, :] = fft_mag
@ -93,7 +105,7 @@ class RingBuffer:
self.distance_axis = compute_distance_axis(
self.last_freqs,
self.fft_bins,
symmetric=self.fft_symmetric,
mode=self.fft_mode,
)
last_idx = (self.head - 1) % self.max_sweeps
@ -107,6 +119,10 @@ class RingBuffer:
self.y_max_fft = float(np.nanmax(finite_db))
return True
def set_symmetric_fft_enabled(self, enabled: bool) -> bool:
"""Backward-compatible wrapper for the old two-state FFT switch."""
return self.set_fft_mode("symmetric" if enabled else "direct")
def push(self, sweep: np.ndarray, freqs: Optional[np.ndarray] = None) -> None:
"""Push a processed sweep and refresh raw/FFT buffers."""
if sweep is None or sweep.size == 0:
@ -123,7 +139,7 @@ class RingBuffer:
if freqs is not None:
self.last_freqs = np.asarray(freqs, dtype=np.float64).copy()
fft_mag = compute_fft_mag_row(sweep, freqs, self.fft_bins, symmetric=self.fft_symmetric)
fft_mag = compute_fft_mag_row(sweep, freqs, self.fft_bins, mode=self.fft_mode)
self.ring_fft[self.head, :] = fft_mag
self.last_fft_db = fft_mag_to_db(fft_mag)
@ -133,7 +149,7 @@ class RingBuffer:
self.y_min_fft = fr_min if self.y_min_fft is None else min(self.y_min_fft, fr_min)
self.y_max_fft = fr_max if self.y_max_fft is None else max(self.y_max_fft, fr_max)
self.distance_axis = compute_distance_axis(freqs, self.fft_bins, symmetric=self.fft_symmetric)
self.distance_axis = compute_distance_axis(freqs, self.fft_bins, mode=self.fft_mode)
self.head = (self.head + 1) % self.max_sweeps
def get_display_raw(self) -> np.ndarray: