You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Give Player 1 and Player 2 independent guitar-input conditioning settings (Input gain, Noise gate, Compressor, Hum filter, Rocksmith gate) in the in-game Audio Bridge overlay's Guitar tab.
Current state
The bridge already runs two input routes: route 0 = P1, route 1 = P2 (AsioHook.cpp:1223; mapping also used in DropPedal.cpp).
The conditioner chain (Hum filter -> Noise gate -> Compressor -> Input gain) is global and P1-only: single atomics + single DSP objects (g_inputGainLinear, g_gateThresholdLinear, g_compressorStrength, g_humFilterBaseHz, g_noiseGate, g_compressor, g_inputLowpass), and the whole block is gated by if (routeIndex == 0 ...) at AsioHook.cpp:1148.
Net result: Player 2's input currently gets zero conditioning. The setters (AsioHook.hpp:31-54) take no route index, so there is no way to address P2.
The "Rocksmith gate" control (op 23) overrides the game's own P1_NoiseFloor calibration (SharedOutput.cpp:234), not our conditioner. The game has a P2_NoiseFloor counterpart.
Design decision
Key per-player settings by physical input route (route 0 = P1, route 1 = P2), not by game profile. The conditioner compensates for physical-input characteristics (a quiet interface input, a ground-loop hum on that cable); profile-mapping would need a fragile game hook and is not guaranteed 1:1. The only control with a genuine native P1/P2 twin is the Rocksmith-gate override (P1_NoiseFloor / P2_NoiseFloor).
Wire protocol
Extend ops 15/19/20/23/24 to accept an optional leading <player>, field, defaulting to route 0 when absent (backward-compatible, no new op numbers):
15 gain: "<player>,<tenths>"
19 gate: "<player>,<tenths>"
20 compressor: "<player>,<pct>"
24 hum: "<player>,<hz>"
23 Rocksmith gate: "<player>,<on>,<tenths>"
Implementation checklist
DLL/Audio/AsioHook.cpp (core): turn the four conditioner atomics (35, 42, 49, 56) into [INPUT_ROUTE_COUNT] arrays; make g_noiseGate (523), g_compressor (643), g_inputLowpass and the hum-notch state per-route arrays (required - these are stateful envelope/biquad followers and the two routes interleave on the audio thread); give the Process*InPlace helpers a route/instance param; remove the routeIndex == 0 gate at 1148 and index every g_* load by routeIndex; add size_t routeIndex to the setters/getters (1773-1851).
DLL/Audio/AsioHook.hpp: update the five setter/getter signatures (31-54) to take routeIndex.
DLL/Audio/SharedOutput.cpp: parse the optional leading <player>, in op cases 15/19/20/23/24 (~222-249), clamp to [0, INPUT_ROUTE_COUNT), pass through.
DLL/Menu.cpp (overlay Guitar tab, 287-338): duplicate the seed vars (246-250) into [2] arrays; add a P1/P2 SegmentedControl shown only when GameState::IsMultiplayer() (same showPlayerTwo gate as the input-2 meter at 271); prefix the player index into every BridgeControl payload.
Rocksmith-gate P2 (deferrable, needs native reversing):RocksmithGate::SetOverride/ApplyPerFrame write P1_NoiseFloor; add a per-player pair targeting P2_NoiseFloor. If deferred, grey out the P2 "Rocksmith gate" row with a tooltip.
Notes / risk
Feature-off path stays bit-exact (every stage no-ops on 0/unity).
P2 gets zero conditioning today, so nothing regresses for existing P1 users.
The four Get*Db getters have no external callers, so per-route conversion is low-impact.
Open questions
Desktop GUI parity - expose the P2 set in AudioRoutingPanel too, or in-game overlay only?
Rocksmith-gate P2 - ship now (locate P2_NoiseFloor) or defer and grey out that one row?
Single-player - hide the P1/P2 selector entirely (default), or always show it?
Summary
Give Player 1 and Player 2 independent guitar-input conditioning settings (Input gain, Noise gate, Compressor, Hum filter, Rocksmith gate) in the in-game Audio Bridge overlay's Guitar tab.
Current state
AsioHook.cpp:1223; mapping also used inDropPedal.cpp).g_inputGainLinear,g_gateThresholdLinear,g_compressorStrength,g_humFilterBaseHz,g_noiseGate,g_compressor,g_inputLowpass), and the whole block is gated byif (routeIndex == 0 ...)atAsioHook.cpp:1148.AsioHook.hpp:31-54) take no route index, so there is no way to address P2.P1_NoiseFloorcalibration (SharedOutput.cpp:234), not our conditioner. The game has aP2_NoiseFloorcounterpart.Design decision
Key per-player settings by physical input route (route 0 = P1, route 1 = P2), not by game profile. The conditioner compensates for physical-input characteristics (a quiet interface input, a ground-loop hum on that cable); profile-mapping would need a fragile game hook and is not guaranteed 1:1. The only control with a genuine native P1/P2 twin is the Rocksmith-gate override (
P1_NoiseFloor/P2_NoiseFloor).Wire protocol
Extend ops 15/19/20/23/24 to accept an optional leading
<player>,field, defaulting to route 0 when absent (backward-compatible, no new op numbers):15gain:"<player>,<tenths>"19gate:"<player>,<tenths>"20compressor:"<player>,<pct>"24hum:"<player>,<hz>"23Rocksmith gate:"<player>,<on>,<tenths>"Implementation checklist
DLL/Audio/AsioHook.cpp(core): turn the four conditioner atomics (35, 42, 49, 56) into[INPUT_ROUTE_COUNT]arrays; makeg_noiseGate(523),g_compressor(643),g_inputLowpassand the hum-notch state per-route arrays (required - these are stateful envelope/biquad followers and the two routes interleave on the audio thread); give theProcess*InPlacehelpers a route/instance param; remove therouteIndex == 0gate at 1148 and index everyg_*load byrouteIndex; addsize_t routeIndexto the setters/getters (1773-1851).DLL/Audio/AsioHook.hpp: update the five setter/getter signatures (31-54) to takerouteIndex.DLL/Audio/SharedOutput.cpp: parse the optional leading<player>,in op cases 15/19/20/23/24 (~222-249), clamp to[0, INPUT_ROUTE_COUNT), pass through.DLL/Menu.cpp(overlay Guitar tab, 287-338): duplicate the seed vars (246-250) into[2]arrays; add a P1/P2SegmentedControlshown only whenGameState::IsMultiplayer()(sameshowPlayerTwogate as the input-2 meter at 271); prefix the player index into everyBridgeControlpayload.DLL/Settings.cpp(150-155 defaults, 282-287 reader);DLL/ModManager.cppseeding (588-640) + launch-active check (166-167);GUI/ReadSettings.csidentifiers +GUI/WriteSettings.csdefault-ini rows (227-232); optionallyGUI/Audio/AudioRoutingPanel.csdesktop controls for parity.RocksmithGate::SetOverride/ApplyPerFramewriteP1_NoiseFloor; add a per-player pair targetingP2_NoiseFloor. If deferred, grey out the P2 "Rocksmith gate" row with a tooltip.Notes / risk
Get*Dbgetters have no external callers, so per-route conversion is low-impact.Open questions
AudioRoutingPaneltoo, or in-game overlay only?P2_NoiseFloor) or defer and grey out that one row?