Skip to content

Per-player (P1/P2) guitar input conditioning settings #93

Description

@Cheesewizard

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

  • 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.
  • Persistence - add P2 keys: DLL/Settings.cpp (150-155 defaults, 282-287 reader); DLL/ModManager.cpp seeding (588-640) + launch-active check (166-167); GUI/ReadSettings.cs identifiers + GUI/WriteSettings.cs default-ini rows (227-232); optionally GUI/Audio/AudioRoutingPanel.cs desktop controls for parity.
  • 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

  1. Desktop GUI parity - expose the P2 set in AudioRoutingPanel too, or in-game overlay only?
  2. Rocksmith-gate P2 - ship now (locate P2_NoiseFloor) or defer and grey out that one row?
  3. Single-player - hide the P1/P2 selector entirely (default), or always show it?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions