diff --git a/apply.sh b/apply.sh index cfc19d3..57f91b8 100755 --- a/apply.sh +++ b/apply.sh @@ -97,6 +97,19 @@ if [ "$FORCE" -eq 0 ]; then fi fi +# --- preserve master volume -------------------------------------------- +SAVED_VOL="" +IS_MUTED=0 +if have wpctl; then + VOL_OUT="$(wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null || true)" + if [ -n "$VOL_OUT" ]; then + SAVED_VOL="$(echo "$VOL_OUT" | awk '{print $2}')" + if echo "$VOL_OUT" | grep -qi "MUTED"; then + IS_MUTED=1 + fi + fi +fi + # --- install ---------------------------------------------------------- if [ "$SIMPLE" -eq 1 ]; then echo "Installing baked FIR files -> $(dirname "$GRAPH_DST")/" @@ -109,8 +122,17 @@ sudo cp "$MERGED" "$GRAPH_DST" echo "Restarting WirePlumber" systemctl --user restart wireplumber -# --- confirm -------------------------------------------------------- +# --- restore master volume --------------------------------------------- sleep 1 +if [ -n "$SAVED_VOL" ] && have wpctl; then + wpctl set-volume @DEFAULT_AUDIO_SINK@ "$SAVED_VOL" 2>/dev/null || true + if [ "$IS_MUTED" -eq 1 ]; then + wpctl set-mute @DEFAULT_AUDIO_SINK@ 1 2>/dev/null || true + fi + echo "ok: preserved master volume (${SAVED_VOL})" +fi + +# --- confirm -------------------------------------------------------- if have wpctl && wpctl status 2>/dev/null | grep -qi "DSP Speakers"; then echo "Done - 'MacBook Pro 15,1 DSP Speakers' sink is up." else diff --git a/bake-graph.py b/bake-graph.py index c271eab..e0833af 100755 --- a/bake-graph.py +++ b/bake-graph.py @@ -266,41 +266,57 @@ def bake_driver_ir(src_wav, dst_wav, is_woofer=False, hp_freq=180.0, driver_gain except Exception as e: print(f"System Voicing Equalizer note: {e}") - # 2.7 Apply User EQ Boosts ("user_eq.json" if present and enabled) + # 2.7 Apply Effective User EQ (user_eq.json override if present, else default user_eq from graph.json) + ueq = None user_eq_path = os.path.join(SCRIPT_DIR, "user_eq.json") if os.path.exists(user_eq_path): try: with open(user_eq_path, 'r') as f: ueq = json.load(f) - if ueq.get("enabled", 1) == 1: - g_out = ueq.get("g_out", 1.0) - if g_out != 1.0: - samples = [s * g_out for s in samples] + except Exception as e: + print(f"Error reading user_eq.json: {e}") - for i in range(8): - f_key = f"f_{i}" - g_key = f"g_{i}" - q_key = f"q_{i}" - ft_key = f"ft_{i}" - if f_key in ueq and g_key in ueq: - f0 = ueq[f_key] - gain = ueq[g_key] - q = ueq.get(q_key, 1.0) - ft = ueq.get(ft_key, 1) - gain_db = 20.0 * math.log10(max(gain, 0.001)) - - if ft == 5: # Low Shelf - b0, b1, b2, a0, a1, a2 = biquad_lowshelf(fs, f0, gain_db, q) - elif ft == 3: # High Shelf - b0, b1, b2, a0, a1, a2 = biquad_highshelf(fs, f0, gain_db, q) - elif ft == 2: # High-Pass - b0, b1, b2, a0, a1, a2 = biquad_highpass(fs, f0, q) - elif ft == 4: # Low-Pass - b0, b1, b2, a0, a1, a2 = biquad_lowpass(fs, f0, q) - else: # Peaking EQ - b0, b1, b2, a0, a1, a2 = biquad_peaking(fs, f0, gain_db, q) + if ueq is None and os.path.exists(graph_path): + try: + with open(graph_path, 'r') as f: + g = json.load(f) + for n in g.get("filter.graph", {}).get("nodes", []): + if n.get("name") == "user_eq": + ueq = n.get("control", {}) + break + except Exception as e: + print(f"Error reading default user_eq from graph.json: {e}") - samples = process_biquad(samples, b0, b1, b2, a0, a1, a2) + if ueq and ueq.get("enabled", 1) == 1: + try: + g_out = ueq.get("g_out", 1.0) + if g_out != 1.0: + samples = [s * g_out for s in samples] + + for i in range(8): + f_key = f"f_{i}" + g_key = f"g_{i}" + q_key = f"q_{i}" + ft_key = f"ft_{i}" + if f_key in ueq and g_key in ueq: + f0 = ueq[f_key] + gain = ueq[g_key] + q = ueq.get(q_key, 1.0) + ft = ueq.get(ft_key, 1) + gain_db = 20.0 * math.log10(max(gain, 0.001)) + + if ft == 5: # Low Shelf + b0, b1, b2, a0, a1, a2 = biquad_lowshelf(fs, f0, gain_db, q) + elif ft == 3: # High Shelf + b0, b1, b2, a0, a1, a2 = biquad_highshelf(fs, f0, gain_db, q) + elif ft == 2: # High-Pass + b0, b1, b2, a0, a1, a2 = biquad_highpass(fs, f0, q) + elif ft == 4: # Low-Pass + b0, b1, b2, a0, a1, a2 = biquad_lowpass(fs, f0, q) + else: # Peaking EQ + b0, b1, b2, a0, a1, a2 = biquad_peaking(fs, f0, gain_db, q) + + samples = process_biquad(samples, b0, b1, b2, a0, a1, a2) except Exception as e: print(f"User EQ processing note: {e}")