Quick Sign In:  

Forum: VirtualDJ Plugins

Topic: Custom mapper for CD-style frame-cueing
After nearly 15+ years and numerous requests for this feature, I finally managed to get CD-style frame-cueing working in VirtualDJ!


It took quite bit of trial and error implementing this enirely in VDJScript, but I was able to mimic much of the functionality of classic dual-deck CD players such as Stanton, Numark, and Denon. No doubt, many DJs that started off by spinning CDs, will feel right at home now :)

This mapper intended for the Numark NDX500, but the frame-cueing functionality can be adapted for just about any controller -- as long as it has a jog wheel, cue button, play button, and any spare button to enable frame-cueing.

Quick Start Guide:

  • Press 'Play' to pause or continue playback. Unlike other mappers, simply pausing the track, will NOT reset the cuepoint.
  • Press 'Cue' to jump back to the cuepoint and pause the track, or hold 'Cue' to briefly preview the track from the cuepoint.
  • Hold 'Tap' to enable frame-cueing, which will pause and stutter the track to aid in setting the cuepoint via the jog wheel.
  • Turntable braking is possible by pressing 'Play' while holding 'Brake'. Use the track-selection knob to adjust the braking speed.
  • Engage any one of the three effects banks by pressing 'Loop In', 'Loop Out', or 'Reloop' (for banks 1 through 3) accordingly.
  • Adjust the primary effect parameter by rotating the jogwheel. The LCD display with show the parameter value (in percent).
  • In Program Mode, use the the track selection knob or the pitch-bend buttons to move the track frame-by-frame when paused.
  • In Program Mode, use the pitch-bend buttons to fast-forward or rewind through the track (with audio scanning during playback).
  • In Program Mode, setup a loop by pressing 'Loop In' for the start and 'Loop Out' for the end. Exit the loop by pressing 'Loop Out'.
  • In Program Mode, press 'Loop In' to set the cuepoint on-the-fly. Press 'Reloop' to bop back to the cuepoint (no loop required).

Of course there is a lot more, which is fully documented in the Add-On (once approved, I'll add the link here).

<?xml version="1.0" encoding="UTF-8"?>
<mapper device="NMNDX5H" author="Intraversal Digital MediaWorks" version="802" date="2022-06-20">
<info>https://bitbucket.org/sorcerykid/workspace/snippets/aEEdG9</info>
<map value="PLAY" action="pause ? set 'playing' 1 & var 'setcue' ? set_cue 0 & play & repeat_start 'play' 2000ms 1 & set 'setcue' 0 : play : set 'playing' 0 & pause" />
<map value="LED_PLAY" action="loaded ? pause ? blink : on : off" />
<map value="CUE" action="goto_cue 0 & var 'playing' ? set 'playing' 0 & pause : play while_pressed" />
<map value="LED_CUE" action="loaded ? var 'setcue' ? blink : var 'cueing' ? on : cue_stop ? blink : on : off" />
<map value="PITCH" action="pitch" />
<map value="PITCHBEND-" action="var 'prog' ? set 'setcue' 1 & var 'tapping' ? repeat 100ms & goto_cue 0 & goto -50ms & set_cue 0 : var 'searching' ? loop_exit & seek -500ms 15ms : var 'playing' ? loop_exit & seek -100ms 15ms : loop_exit & seek -50ms 120ms : pitch_bend -3% 500ms" />
<map value="PITCHBEND+" action="var 'prog' ? set 'setcue' 1 & var 'tapping' ? repeat 100ms & goto_cue 0 & goto +50ms & set_cue 0 : var 'searching' ? loop_exit & seek +500ms 15ms : var 'playing' ? loop_exit & seek +100ms 15ms : loop_exit & seek +50ms 120ms : pitch_bend +3% 500ms" />
<map value="TAP" action="down ? set 'playing' 0 & set 'tapping' 1 & loop_exit & set_cue 0 & play & repeat_start 'stutter' 150ms & hot_cue 0 : toggle 'tapping' & hot_cue 0 & pause & repeat_stop 'stutter' " />
<map value="REC" action="set 'delcue' 1 while_pressed" />
<map value="HOTCUE1" action="var 'single' ? var 'delcue' ? delete_cue 5 : set 'playing' 0 & pause & has_cue 5 ? goto_cue 5 & play while_pressed : set_cue 5 & cue_color 5 'yellow' : var 'delcue' ? delete_cue 1 : set 'playing' 1 & play & has_cue 1 ? goto_cue 1 : set_cue 1" />
<map value="HOTCUE2" action="var 'single' ? var 'delcue' ? delete_cue 6 : set 'playing' 0 & pause & has_cue 6 ? goto_cue 6 & play while_pressed : set_cue 6 & cue_color 6 'yellow' : var 'delcue' ? delete_cue 2 : set 'playing' 1 & play & has_cue 2 ? goto_cue 2 : set_cue 2" />
<map value="HOTCUE3" action="var 'single' ? var 'delcue' ? delete_cue 7 : set 'playing' 0 & pause & has_cue 7 ? goto_cue 7 & play while_pressed : set_cue 7 & cue_color 7 'yellow' : var 'delcue' ? delete_cue 3 : set 'playing' 1 & play & has_cue 3 ? goto_cue 3 : set_cue 3" />
<map value="LED_HOTCUE1" action="var 'single' ? var 'delcue' ? hot_cue 5 ? blink 400ms : off : hot_cue 5 : var 'delcue' ? hot_cue 1 ? blink 400ms : off : hot_cue 1" />
<map value="LED_HOTCUE2" action="var 'single' ? var 'delcue' ? hot_cue 6 ? blink 400ms : off : hot_cue 6 : var 'delcue' ? hot_cue 2 ? blink 400ms : off : hot_cue 2" />
<map value="LED_HOTCUE3" action="var 'single' ? var 'delcue' ? hot_cue 7 ? blink 400ms : off : hot_cue 7 : var 'delcue' ? hot_cue 3 ? blink 400ms : off : hot_cue 3" />
<map value="PITCH_RANGE" action="pitch_range '4,8,16,100' +1" />
<map value="LED_PITCH_16" action="pitch_range 16%" />
<map value="LED_PITCH_4" action="pitch_range 4%" />
<map value="LED_PITCH_8" action="pitch_range 8%" />
<map value="LED_PITCH_ALL" action="pitch_range 100%" />
<map value="LED_SCRATCH" action="vinyl_mode ? on : off" />
<map value="SEARCH" action="toggle 'searching' & vinyl_mode 0" />
<map value="LED_SEARCH" action="var 'searching' ? on : off" />
<map value="REVERSE" action="slip_mode ? dump : reverse" />
<map value="LED_REVERSE" action="reverse ? on : off" />
<map value="TRACK_PUSH" action="var 'delcue' ? sidelist_add : browser_window 'folders' ? browser_enter : load" />
<map value="FOLDER" action="browser_window 'folders' ? browser_window 'sideview' : browser_window 'folders'" />
<map value="TIME" action="display_time 'remain,elapsed' +1 & refresh_controller" />
<map value="SINGLE" action="holding ? edit_poi : toggle 'single' & cue_color 5 'yellow' & cue_color 6 'yellow' & cue_color 7 'yellow'" />
<map value="LOOPOUT" action="var 'prog' ? loop ? loop_exit : loop_out : effect_active 2 ? set 'looping' 0 & effect_active 2 off : set 'looping' 1 & effect_disable_all & effect_active 2 on & & effect_slider 2 1 50%" />
<map value="LED_LOOPIN" action="var 'prog' ? loaded ? loop ? blink : on : off : effect_active 1 ? blink 500ms : off" />
<map value="LED_LOOPOUT" action="var 'prog' ? loop ? blink : off : effect_active 2 ? blink 500ms : off" />
<map value="RELOOP" action="var 'prog' ? set 'playing' 1 & goto_cue 0 & play : effect_active 3 ? set 'looping' 0 & effect_active 3 off : set 'looping' 1 & effect_disable_all & effect_active 3 on & effect_slider 3 1 0%" />
<map value="LCD_PAUSE" action="var 'playing' ? off : on" />
<map value="LCD_ELAPSED" action="display_time 'elapsed'" />
<map value="LCD_REMAIN" action="display_time 'remain'" />
<map value="DIGIT_MIN" action="get_time_min 'absolute'" />
<map value="DIGIT_SEC" action="get_time_sec 'absolute'" />
<map value="DIGIT_FRAME" action="get_time_msf 'absolute'" />
<map value="LCD_PITCH" action="effect_active 1 ? off : effect_active 2 ? off : effect_active 3 ? off : var 'braking' ? off : on" />
<map value="LCD_PITCH_SIGN" action="effect_active 1 ? off : effect_active 2 ? off : effect_active 3 ? off : var 'braking' ? off : on" />
<map value="DIGIT_DECK" action="get deck" />
<map value="DIGIT_BPM" action="loaded ? get bpm : nothing" />
<map value="TEXT" action="loaded ? var 'text_mode' 1 ? get_loaded_song 'album' : var 'text_mode' 2 ? get_title : var 'text_mode' 3 ? get_artist_title : get_artist : get_text 'No track'" />
<map value="LCD_ARTIST" action="loaded ? var 'text_mode' 0 ? on : var 'text_mode' 3 ? on : off" />
<map value="LCD_ALBUM" action="loaded ? var 'text_mode' 1 ? on : off" />
<map value="LCD_TITLE" action="loaded ? var 'text_mode' 2 ? on : var 'text_mode' 3 ? on : off" />
<map value="LCD_TIME_DOTS" action="on" />
<map value="LCD_BPM_OFF" action="on" />
<map value="LCD_BPM" action="on" />
<map value="LCD_TIME_OFF" action="on" />
<map value="LCD_AUTOCUE" action="auto_cue" />
<map value="LCD_AUTO" action="beatlock" />
<map value="LCD_MT" action="key_lock" />
<map value="LCD_RELOOP" action="var 'prog' ? loop ? on : off" />
<map value="LCD_CONTINUE" action="var 'single' ? on : off" />
<map value="LCD_FOLDER" action="browser_window 'folders'" />
<map value="DIGIT_PITCH" action="var 'braking' ? brakespeed & param_multiply 250 : effect_active 1 ? effect_slider 1 1 & param_multiply 100 : effect_active 2 ? effect_slider 2 1 & param_multiply 100 : effect_active 3 ? effect_slider 3 1 & param_multiply 100 : pitch_range 100% ? get_pitch : get_pitch & param_multiply 100" />
<map value="LCD_PITCH_DOT" action="pitch_range 100% ? off : on" />
<map value="LCD_PLAY" action="var 'playing' ? on : off" />
<map value="BAR1_PROGRESS" action="display_time 'total' ? constant 0.5 : display_time 'elapsed' ? song_pos & param_multiply 0.5 : song_pos & param_multiply 0.5 & param_add 0.5" />
<map value="BAR2_PROGRESS" action="display_time 'total' ? constant 0.5 : display_time 'remain' ? song_pos & param_multiply 0.5 : song_pos & param_multiply 0.5 & param_add 0.5" />
<map value="LCD_TOTAL" action="display_time 'total'" />
<map value="MIDI_MODE" action="down ? refresh_controller & mute off : mute on" />
<map value="LED_BRAKE" action="brakespeed 0% ? off : on" />
<map value="BRAKE" action="set 'braking' 1 while_pressed & down ? brakespeed 20% & startupspeed 20% : brakespeed 0% & startupspeed 0%" />
<map value="LCD_CUE" action="var 'tapping' ? off : cue_stop" />
<map value="JOG" action="effect_active 1 ? effect_slider 1 1 : effect_active 2 ? effect_slider 2 1 : effect_active 3 ? effect_slider 3 1 : var 'tapping' ? param_bigger 0.0016 ? set 'jogging' 1 & set 'setcue' 1 : param_smaller -0.0016 ? set 'jogging' -1 & set 'setcue' 1 : set 'jogging' 0 : var 'searching' ? param_bigger 0.0016 ? goto +250ms & set 'setcue' 1 : param_smaller -0.0016 ? goto -250ms & set 'setcue' 1 : nothing : touchwheel" />
<map value="LOOPIN" action="var 'prog' ? loop ? loop_exit : set_cue 0 : effect_active 1 ? set 'looping' 0 & effect_active 1 off : set 'looping' 1 & effect_disable_all & effect_active 1 on & effect_slider 1 1 50%" />
<map value="LED_RELOOP" action="off" />
<map value="LCD_PITCH_OFF" action="on" />
<map value="LCD_TRACK" action="on" />
<map value="TRACK_ENC" action="var 'braking' ? param_equal -1 ? brakespeed 10% ? nothing : brakespeed -10% & startupspeed -10% : brakespeed 30% ? nothing : brakespeed +10% & startupspeed +10% : var 'tapping' ? set 'setcue' 1 & goto_cue 0 & param_equal -1 ? goto -50ms & param_multiply 0 & set_cue : goto +50ms & param_multiply 0 & set_cue : browser_scroll" />
<map value="JOG_TOUCH" action="var 'tapping' ? repeat 80ms & var_equal 'jogging' 1 ? goto_cue 0 & goto +50ms & set_cue 0 : var_equal 'jogging' -1 ? goto_cue 0 & goto -50ms & set_cue 0 : nothing : var 'searching' ? nothing : var 'looping' ? nothing : touchwheel_touch" />
<map value="MASTERTEMPO" action="key_lock" />
<map value="SCRATCH" action="vinyl_mode & slip_mode off & set 'searching' 0" />
<map value="PROG" action="toggle 'prog' & effect_disable_all" />
<map value="LCD_PROG" action="var 'prog'" />
</mapper>
 

geposted Mon 20 Jun 22 @ 8:10 pm
A new version of the mapper is available. This is mostly a bug fix release, as it addresses a number of quirks:

* Fixed: The 'Cue' button keeps flashing after starting playback from a hot cue.
* Fixed: Allow scanning through the track by simply holding the 'Search' button.
* Fixed: Engaging the search functionality should not deactivate Scratch Mode.
* Fixed: Remove extraneous frame-seeking code from the Pitch Bend buttons.

Most importantly you will notice that setting of cuepoints is far more consistent. The only buttons that reset the cuepoint are 'Tap', 'Loop In', and the hotcues. All other functions such as scratching, braking, reversing, scanning, pausing, etc. preserve the cupoint.

As a bonus, the primary effect parameter can now be preserved by holding 'Rec' when re-engaging the effect.


<?xml version="1.0" encoding="UTF-8"?>
<mapper device="NMNDX5H" author="Intraversal Digital MediaWorks" version="802" date="2022-06-21">
<info>https://bitbucket.org/sorcerykid/workspace/snippets/aEEdG9</info>
<map value="PLAY" action="pause ? set 'playing' 1 & var 'setcue' ? set_cue 0 & play & repeat_start 'play' 2000ms 1 & set 'setcue' 0 : play : set 'playing' 0 & pause" />
<map value="LED_PLAY" action="loaded ? pause ? blink : on : off" />
<map value="CUE" action="goto_cue 0 & var 'playing' ? set 'playing' 0 & pause : play while_pressed" />
<map value="LED_CUE" action="loaded ? var 'setcue' ? blink : var 'tapping' ? on : cue_stop ? blink : on : off" />
<map value="PITCH" action="pitch" />
<map value="PITCHBEND-" action="var 'prog' ? var 'tapping' ? repeat 100ms & goto_cue 0 & goto -50ms & set_cue 0 : var 'playing' ? loop_exit & seek -100ms 15ms : loop_exit & seek -50ms 120ms : pitch_bend -3% 500ms" />
<map value="PITCHBEND+" action="var 'prog' ? var 'tapping' ? repeat 100ms & goto_cue 0 & goto +50ms & set_cue 0 : var 'playing' ? loop_exit & seek +100ms 15ms : loop_exit & seek +50ms 120ms : pitch_bend +3% 500ms" />
<map value="TAP" action="down ? set 'setcue' 1 & set 'playing' 0 & set 'tapping' 1 & loop_exit & set_cue 0 & play & repeat_start 'stutter' 150ms & hot_cue 0 : set 'tapping' 0 & hot_cue 0 & pause & repeat_stop 'stutter' " />
<map value="REC" action="set 'delcue' 1 while_pressed" />
<map value="HOTCUE1" action="var 'single' ? var 'delcue' ? delete_cue 5 : set 'playing' 0 & pause & has_cue 5 ? goto_cue 5 & play while_pressed : set_cue 5 & cue_color 5 'yellow' : var 'delcue' ? delete_cue 1 : set 'playing' 1 & play & has_cue 1 ? goto_cue 1 : set_cue 1 & set 'setcue' 1 & repeat_start 'play' 2000ms 1 & set 'setcue' 0" />
<map value="HOTCUE2" action="var 'single' ? var 'delcue' ? delete_cue 6 : set 'playing' 0 & pause & has_cue 6 ? goto_cue 6 & play while_pressed : set_cue 6 & cue_color 6 'yellow' : var 'delcue' ? delete_cue 2 : set 'playing' 1 & play & has_cue 2 ? goto_cue 2 : set_cue 2 & set 'setcue' 1 & repeat_start 'play' 2000ms 1 & set 'setcue' 0" />
<map value="HOTCUE3" action="var 'single' ? var 'delcue' ? delete_cue 7 : set 'playing' 0 & pause & has_cue 7 ? goto_cue 7 & play while_pressed : set_cue 7 & cue_color 7 'yellow' : var 'delcue' ? delete_cue 3 : set 'playing' 1 & play & has_cue 3 ? goto_cue 3 : set_cue 3 & set 'setcue' 1 & repeat_start 'play' 2000ms 1 & set 'setcue' 0" />
<map value="LED_HOTCUE1" action="var 'single' ? var 'delcue' ? hot_cue 5 ? blink 400ms : off : hot_cue 5 : var 'delcue' ? hot_cue 1 ? blink 400ms : off : hot_cue 1" />
<map value="LED_HOTCUE2" action="var 'single' ? var 'delcue' ? hot_cue 6 ? blink 400ms : off : hot_cue 6 : var 'delcue' ? hot_cue 2 ? blink 400ms : off : hot_cue 2" />
<map value="LED_HOTCUE3" action="var 'single' ? var 'delcue' ? hot_cue 7 ? blink 400ms : off : hot_cue 7 : var 'delcue' ? hot_cue 3 ? blink 400ms : off : hot_cue 3" />
<map value="PITCH_RANGE" action="pitch_range '4,8,16,100' +1" />
<map value="LED_PITCH_16" action="pitch_range 16%" />
<map value="LED_PITCH_4" action="pitch_range 4%" />
<map value="LED_PITCH_8" action="pitch_range 8%" />
<map value="LED_PITCH_ALL" action="pitch_range 100%" />
<map value="LED_SCRATCH" action="vinyl_mode ? on : off" />
<map value="LED_SEARCH" action="var 'searching' ? on : off" />
<map value="REVERSE" action="slip_mode ? dump : reverse" />
<map value="LED_REVERSE" action="reverse ? on : off" />
<map value="TRACK_PUSH" action="var 'delcue' ? sidelist_add : browser_window 'folders' ? browser_enter : load" />
<map value="FOLDER" action="browser_window 'folders' ? browser_window 'sideview' : browser_window 'folders'" />
<map value="TIME" action="display_time 'remain,elapsed' +1 & refresh_controller" />
<map value="SINGLE" action="holding ? edit_poi : toggle 'single' & cue_color 5 'yellow' & cue_color 6 'yellow' & cue_color 7 'yellow'" />
<map value="LOOPOUT" action="var 'prog' ? loop ? loop_exit : loop_out : effect_active 2 ? set 'looping' 0 & effect_active 2 off : set 'looping' 1 & effect_disable_all & effect_active 2 on & var 'delcue' ? nothing : effect_slider 2 1 0%" />
<map value="LED_LOOPIN" action="var 'prog' ? loaded ? loop ? blink : on : off : effect_active 1 ? blink 500ms : off" />
<map value="LED_LOOPOUT" action="var 'prog' ? loop ? blink : off : effect_active 2 ? blink 500ms : off" />
<map value="RELOOP" action="var 'prog' ? set 'playing' 1 & goto_cue 0 & play : effect_active 3 ? set 'looping' 0 & effect_active 3 off : set 'looping' 1 & effect_disable_all & effect_active 3 on & var 'delcue' ? nothing : effect_slider 3 1 50%" />
<map value="LCD_PAUSE" action="var 'playing' ? off : on" />
<map value="LCD_ELAPSED" action="display_time 'elapsed'" />
<map value="LCD_REMAIN" action="display_time 'remain'" />
<map value="DIGIT_MIN" action="get_time_min 'absolute'" />
<map value="DIGIT_SEC" action="get_time_sec 'absolute'" />
<map value="DIGIT_FRAME" action="get_time_msf 'absolute'" />
<map value="LCD_PITCH" action="effect_active 1 ? off : effect_active 2 ? off : effect_active 3 ? off : var 'braking' ? off : on" />
<map value="LCD_PITCH_SIGN" action="effect_active 1 ? off : effect_active 2 ? off : effect_active 3 ? off : var 'braking' ? off : on" />
<map value="DIGIT_DECK" action="get deck" />
<map value="DIGIT_BPM" action="loaded ? get bpm : nothing" />
<map value="TEXT" action="loaded ? var 'text_mode' 1 ? get_loaded_song 'album' : var 'text_mode' 2 ? get_title : var 'text_mode' 3 ? get_artist_title : get_artist : get_text 'No track'" />
<map value="LCD_ARTIST" action="loaded ? var 'text_mode' 0 ? on : var 'text_mode' 3 ? on : off" />
<map value="LCD_ALBUM" action="loaded ? var 'text_mode' 1 ? on : off" />
<map value="LCD_TITLE" action="loaded ? var 'text_mode' 2 ? on : var 'text_mode' 3 ? on : off" />
<map value="LCD_TIME_DOTS" action="on" />
<map value="LCD_BPM_OFF" action="on" />
<map value="LCD_BPM" action="on" />
<map value="LCD_TIME_OFF" action="on" />
<map value="LCD_AUTOCUE" action="auto_cue" />
<map value="LCD_AUTO" action="beatlock" />
<map value="LCD_MT" action="key_lock" />
<map value="LCD_RELOOP" action="var 'prog' ? loop ? on : off" />
<map value="LCD_CONTINUE" action="var 'single' ? on : off" />
<map value="LCD_FOLDER" action="browser_window 'folders'" />
<map value="DIGIT_PITCH" action="var 'braking' ? brakespeed & param_multiply 250 : effect_active 1 ? effect_slider 1 1 & param_multiply 100 : effect_active 2 ? effect_slider 2 1 & param_multiply 100 : effect_active 3 ? effect_slider 3 1 & param_multiply 100 : pitch_range 100% ? get_pitch : get_pitch & param_multiply 100" />
<map value="LCD_PITCH_DOT" action="pitch_range 100% ? off : on" />
<map value="LCD_PLAY" action="var 'playing' ? on : off" />
<map value="BAR1_PROGRESS" action="display_time 'total' ? constant 0.5 : display_time 'elapsed' ? song_pos & param_multiply 0.5 : song_pos & param_multiply 0.5 & param_add 0.5" />
<map value="BAR2_PROGRESS" action="display_time 'total' ? constant 0.5 : display_time 'remain' ? song_pos & param_multiply 0.5 : song_pos & param_multiply 0.5 & param_add 0.5" />
<map value="LCD_TOTAL" action="display_time 'total'" />
<map value="MIDI_MODE" action="down ? refresh_controller & mute off : mute on" />
<map value="LED_BRAKE" action="brakespeed 0% ? off : on" />
<map value="BRAKE" action="down ? set 'braking' 1 & brakespeed 20% & startupspeed 20% : set 'braking' 0 & brakespeed 0% & startupspeed 0%" />
<map value="LCD_CUE" action="var 'tapping' ? off : cue_stop" />
<map value="JOG" action="effect_active 1 ? effect_slider 1 1 : effect_active 2 ? effect_slider 2 1 : effect_active 3 ? effect_slider 3 1 : var 'tapping' ? param_bigger 0.0016 ? set 'jogging' 1 & set 'setcue' 1 : param_smaller -0.0016 ? set 'jogging' -1 & set 'setcue' 1 : set 'jogging' 0 : var 'searching' ? param_bigger 0.0016 ? goto +250ms : param_smaller -0.0016 ? goto -250ms : nothing : touchwheel" />
<map value="LOOPIN" action="var 'prog' ? loop ? loop_exit : set_cue 0 & set 'setcue' 1 & repeat_start 'play' 2000ms 1 & set 'setcue' 0 : effect_active 1 ? set 'looping' 0 & effect_active 1 off : set 'looping' 1 & effect_disable_all & effect_active 1 on & var 'delcue' ? nothing : effect_slider 1 1 50%" />
<map value="LED_RELOOP" action="off" />
<map value="LCD_PITCH_OFF" action="on" />
<map value="LCD_TRACK" action="on" />
<map value="TRACK_ENC" action="var 'braking' ? param_equal -1 ? brakespeed 10% ? nothing : brakespeed -10% & startupspeed -10% : brakespeed 30% ? nothing : brakespeed +10% & startupspeed +10% : var 'tapping' ? set 'setcue' 1 & goto_cue 0 & param_equal -1 ? goto -50ms & param_multiply 0 & set_cue : goto +50ms & param_multiply 0 & set_cue : browser_scroll" />
<map value="JOG_TOUCH" action="var 'tapping' ? repeat 80ms & var_equal 'jogging' 1 ? goto_cue 0 & goto +50ms & set_cue 0 : var_equal 'jogging' -1 ? goto_cue 0 & goto -50ms & set_cue 0 : nothing : var 'searching' ? nothing : var 'looping' ? nothing : touchwheel_touch" />
<map value="MASTERTEMPO" action="key_lock" />
<map value="SCRATCH" action="vinyl_mode & slip_mode off" />
<map value="PROG" action="toggle 'prog' & effect_disable_all" />
<map value="LCD_PROG" action="var 'prog'" />
<map value="SEARCH" action="down ? set 'searching' 1 : set 'searching' 0" />
</mapper>
 

geposted Wed 06 Jul 22 @ 7:54 pm
Quick update: There seems to be a bug where the jogwheel completely ceases to function, presumably after switching to Program Mode. This affects the ability to scratch, to search, to pitch bend, etc. I'm still trying to isolate the exact cause of the issue. I'll make a patch available here as soon as I can.
 

geposted Tue 19 Jul 22 @ 9:16 pm
After some more investigation, I've determined the non-responsive jogwheel is likely due to a hardware bug. The workaround is therefore to turn off the unit, then turn it back on. That will restore full functionality.
 

geposted Sun 24 Jul 22 @ 6:42 pm