Split deck mode now has its own URL at /decks/, while the main player remains at /musicplayer_ui.html.
Closing deck mode from /decks/ returns the user to the main music player instead of leaving them on the deck route.
DJ display mode now uses JavaScript detection, with an INFO-panel override for Auto, Mobile, Tablet, and PC.
The login button is back in the horizontally scrollable DJ titlebar, with the status text hidden on tight mobile layouts.
Jog wheels were enlarged and now support drag-to-seek, scratch-style pitch bend, and rapid back-and-forth vinyl scratch bursts.
Dedicated scratch pads were added so users can deliberately drag the track forward/backward while real scratch samples provide the wika-wika texture.
Pitch faders remain at the normal ±8% deck range and now update the displayed effective BPM in real time.
DJ EQ was added as DjEqActor; moving HI, MID, or LO auto-enables it, and RESET EQ returns the deck EQ to flat.
The master VOL knob is wired and can boost output above 100%, up to 250%.
Duplicate transport cue controls were removed, leaving one main CUE button per deck plus the hot cue pads.
HEAD remains documented as a monitor-plan control until a dedicated headphone output actor is added.
Display Mode
Use AUTO for browser detection, or force a layout when the deck UI guesses wrong.
Mode: auto
Deck Loading and Playback
LOAD opens the track picker for Deck A or Deck B.
PLAY starts or pauses that deck through DeckActor.
The jog wheel scrubs through the song while dragging and adds a scratch-style bend.
Rapid back-and-forth jog motion triggers a short vinyl-style scratch burst.
The scratch pad behaves more like virtual vinyl: horizontal drag moves the track forward/backward while vertical height changes sample pitch/filter tone.
EJECT clears the loaded deck.
Faders and Output
Channel faders control each deck volume with DeckActor.SET_VOLUME.
The crossfader blends Deck A and Deck B using equal-power curves.
Pitch faders change deck playback speed through DeckActor.SET_PITCH.
BPM readouts show effective BPM as base BPM multiplied by the current pitch ratio.
VOL is master output and can boost above 100%, up to 250%.
HEAD is reserved for headphone monitor gain. It is visual until DjMonitorActor lands.
DJ EQ
HI, MID, and LO use DjEqActor, separate from the normal music player EQ.
The visible centre HI/MID/LO knobs are the current shared DJ EQ for both decks, not separate Deck A and Deck B EQ drawers.
Moving any HI/MID/LO knob automatically enables DJ EQ.
RESET EQ returns HI/MID/LO to 0dB and bypasses DJ EQ.
Separate per-deck HI/MID/LO controls are not exposed yet. That is a PC-version control pass still to build.
FX in the centre strip controls scratch-pad send gain from 0dB to +30dB.
FX Rack
To open the per-deck rack, press the FX button on Deck A or Deck B. That reveals that deck's reverb, delay, and filter controls.
FX rack knobs are audio-wired through FxActor.
FX output preserves the DJ EQ path when the FX graph is active.
Scratch samples always play from the scratch pad. The centre FX knob adds extra dB gain for stronger scratch throws.
Pitch and BPM
The pitch range is ±8%, a normal fine-control DJ deck default.
The server detects and caches the base BPM for the loaded track.
The UI keeps that base value in dataset.raw so sync logic still has a clean source value.
When pitch changes, the deck display renders base BPM × playbackRate instead of re-sampling audio.
This is lighter than live BPM analysis and accurate for pitch-slider speed changes.
Cue Behavior
Hot cue pads store or jump to cue points through CueActor.
There is one main CUE button per deck in the transport bar.
If cue 0 is empty, pressing CUE stores the current position first.
When paused, holding CUE plays from cue; releasing pauses and returns to cue.
When already playing, pressing CUE jumps back to cue 0.
Monitor Plan
Next actor should be DjMonitorActor.
It should tap deck sources before the main faders so a quiet deck can still be previewed.
HEAD will control monitor gain.
Browser output selection should use a monitor audio element plus setSinkId() where supported.