fix: NAM engine stability and hum — post-NAM DC blocker + HPF, warm-before-kill subprocess swap, non-blocking pipe I/O, sample rate sync, arch detection

- Add first-order DC blocker (R=0.999) after NAM processing to kill subsonic offset
- Add 80Hz Butterworth HPF after NAM to catch residual 60/120Hz hum
- Recompute HPF coefficients on sample rate change in set_audio_profile()
- Warm-before-kill: spawn new C++ subprocess before stopping old one (no gap)
- Add background reader thread for non-blocking stdout consumption
- Reuse last known output frame if engine is slow (keeps stream aligned)
- Pass sample_rate to NAMEngineProcess and FastNAMHost constructors
- Forward sample_rate in server.py profile change and main.py init
- Read actual architecture from .nam files instead of hardcoding 'LSTM'
- Add threading.Lock to FastNAMHost for safe engine ref swaps
This commit is contained in:
2026-06-19 14:13:44 -04:00
parent acdff5eb9b
commit 04931fd738
6 changed files with 349 additions and 75 deletions
+3 -2
View File
@@ -201,7 +201,8 @@ class PedalApp:
# ── 2. DSP pipeline (NAM + IR + FX chain) ────────────
block_size = self.audio_config.latency_profile["period"]
self.nam_host = NAMEngineRouter(block_size=block_size)
sample_rate = self.audio_config.latency_profile.get("rate", 48000)
self.nam_host = NAMEngineRouter(block_size=block_size, sample_rate=sample_rate)
self.ir_loader = IRLoader()
self.pipeline = AudioPipeline(nam_host=self.nam_host, ir_loader=self.ir_loader)
self.nam_host.warm_up()
@@ -248,7 +249,7 @@ class PedalApp:
self.bass_nam_host: NAMEngineRouter | None = None
self.bass_ir_loader: IRLoader | None = None
if multi_ch_enabled:
self.bass_nam_host = NAMEngineRouter(block_size=block_size)
self.bass_nam_host = NAMEngineRouter(block_size=block_size, sample_rate=sample_rate)
self.bass_ir_loader = IRLoader()
self.bass_pipeline = AudioPipeline(
nam_host=self.bass_nam_host,