diff --git a/sync_audio_test.py b/sync_audio_test.py index ba74258..4447bdd 100644 --- a/sync_audio_test.py +++ b/sync_audio_test.py @@ -44,6 +44,7 @@ except ImportError: HAS_SD = False from sync_audio import load_wav, correlate, device_info, lag_to_seconds +from waveform_cache import cached_load_wav def load_config(path: str) -> dict: @@ -131,9 +132,9 @@ class SyncWindow(QtWidgets.QMainWindow): # load print(f"Loading {a_path}") - self.a, self.sr_a = load_wav(a_path, target_sr=sr) + self.a, self.sr_a = cached_load_wav(a_path, target_sr=sr) print(f"Loading {b_path}") - self.b, self.sr_b = load_wav(b_path, target_sr=sr) + self.b, self.sr_b = cached_load_wav(b_path, target_sr=sr) # keep originals for lag apply self.a_orig = self.a.copy() self.b_orig = self.b.copy() diff --git a/verify_sync.py b/verify_sync.py index 5e38537..5712c6a 100644 --- a/verify_sync.py +++ b/verify_sync.py @@ -61,6 +61,7 @@ except ImportError: HAS_SF = False from sync_audio import load_wav +from waveform_cache import cached_load_wav # ─── Helpers ─── @@ -209,9 +210,9 @@ class VerifyWindow(QtWidgets.QMainWindow): # Load audio print(f"Loading audio A: {wav_a_path}") - self.a_orig, _ = load_wav(wav_a_path, target_sr=sr) + self.a_orig, _ = cached_load_wav(wav_a_path, target_sr=sr) print(f"Loading audio B: {wav_b_path}") - self.b_orig, _ = load_wav(wav_b_path, target_sr=sr) + self.b_orig, _ = cached_load_wav(wav_b_path, target_sr=sr) # Apply lag alignment self.a_aligned, self.b_aligned = apply_lag(self.a_orig, self.b_orig, self.lag_samples) diff --git a/waveform_cache.py b/waveform_cache.py new file mode 100644 index 0000000..f99b25a --- /dev/null +++ b/waveform_cache.py @@ -0,0 +1,29 @@ +""" +Shared waveform cache — avoids re-reading and re-decoding large WAV files +when the same file is loaded multiple times (e.g. sync_audio_test → verify). +""" + +from __future__ import annotations +import os +import numpy as np + +_cache: dict[tuple[str, int], np.ndarray] = {} + + +def cached_load_wav(path: str, target_sr: int = 48000) -> tuple[np.ndarray, int]: + """Load a WAV file with caching. Returns (audio_array, sample_rate).""" + real_path = os.path.realpath(path) + key = (real_path, target_sr) + if key in _cache: + print(f" (cached: {os.path.basename(path)})") + return _cache[key].copy(), target_sr + + # Import here to avoid circular imports + from sync_audio import load_wav + data, sr = load_wav(path, target_sr=target_sr) + _cache[key] = data + return data, sr + + +def clear_cache(): + _cache.clear()