Skip to content

DualSense Controller

VIIPER emulates complete USB-connected DualSense and DualSense Edge devices, including controls, touch, motion, adaptive triggers, lightbar, speaker, advanced haptics, and microphone endpoints.

Supported device types

VIIPER 0.0.8 exposes only the production V5 contracts:

Device type USB functions
dualsensecombinedaudioduplexv5 DualSense HID, speaker/haptics OUT, microphone IN
dualsenseaudioonlyduplexv5 DualSense speaker/haptics OUT and microphone IN sidecar
dualsenseedgecombinedaudioduplexv5 DualSense Edge HID, speaker/haptics OUT, microphone IN

The old raw, extended, V1, V2, V3, and V4 names are intentionally not registered. Clients must use V5; VIIPER does not silently negotiate an older header or split audio/state transport.

V5 stream contract

Every packet uses a 16-byte header followed by its payload:

Offset Size Field
0 4 ASCII VPCM
4 1 Version 0x05
5 1 Frame type
6 2 Payload length, little endian
8 4 Monotonic sequence, little endian
12 4 IEEE CRC32, little endian

The CRC covers header bytes 4 through 11 followed by the payload. Sequence numbers are shared by every frame type in one direction. A version mismatch, sequence gap, CRC mismatch, invalid payload length, or unknown frame type closes the stream instead of changing protocols.

Direction Type Payload
Client to VIIPER 0x01 33-byte controller input state
Client to VIIPER 0x02 1,920-byte microphone PCM block: stereo S16LE, 48 kHz, 10 ms
VIIPER to client 0x81 474-byte current combined controller feedback
VIIPER to client 0x83 Atomic feedback plus the matching 1,920-byte speaker PCM generation

An atomic 0x83 payload begins with a little-endian 16-bit feedback length, then the 474-byte feedback object, then exactly 480 stereo S16LE speaker frames. The four-channel virtual USB source is preserved at 48 kHz: front left/right become the speaker generation, while rear left/right independently complete the 512-frame advanced-haptics clock. At each 480-frame presentation boundary VIIPER consumes one completed rear sample or emits silence for that lane, matching the proven V5 cadence without replaying stale haptics.

Controller state, adaptive triggers, lightbar, rumble, haptics, and speaker data are serialized by one V5 writer. Media backpressure is bounded and newest-wins; interface resets form a hard generation boundary so stale audio cannot cross a stop/reconnect.

Input state

The 33-byte input payload is little endian:

  • Sticks: LX, LY, RX, RY as signed 8-bit values.
  • Buttons: 32-bit bitfield.
  • D-pad: 8-bit bitfield.
  • L2 and R2: unsigned 8-bit values.
  • Two touch contacts: X/Y, active flag, and tracking ID.
  • Gyroscope and accelerometer: three signed 16-bit axes each.

Button bits:

Control Value
Square 0x00000010
Cross 0x00000020
Circle 0x00000040
Triangle 0x00000080
L1 / R1 0x00000100 / 0x00000200
L2 / R2 0x00000400 / 0x00000800
Create / Options 0x00001000 / 0x00002000
L3 / R3 0x00004000 / 0x00008000
PS 0x00010000
Touchpad click 0x00020000
Mic mute 0x00040000
Edge LFn / RFn 0x00100000 / 0x00200000
Edge L4 / R4 0x00400000 / 0x00800000

D-pad bits are Up 0x01, Down 0x02, Left 0x04, and Right 0x08.

Feedback state

The 474-byte V5 feedback object contains:

  • Bytes 0 through 5: compatible rumble, lightbar RGB, and player LEDs.
  • Bytes 6 through 27: native-spaced R2 and L2 adaptive-trigger blocks.
  • Bytes 28 through 75: the native 48-byte USB output report 0x02.
  • Bytes 76 through 473: the current 398-byte combined Bluetooth carrier.

The combined carrier keeps state and media on one presentation clock. The physical-controller bridge supplies the encoded speaker lane and forwards it using its V5 transport.