Serato DJ Pro General Discussion

Talk about Serato DJ Pro, expansion packs and supported hardware

XML Midi mapping

djeyewater 5:11 PM - 21 July, 2019
I'm trying to midi map the Denon SC3900, though most of these questions aren't specific to that unit.

It seems that modifiers work in 2.1.0 but not in 2.1.1 and later. How do we work with modifiers in the current version?

I can't get the output lighting to change at all. In the case of the SC3900 the lighting is assigned to a different control than the actual control, then the value passed determines the control and light state. There is some discussion on this subject here: serato.com but it doesn't work for me. I'm wondering if this is something that has changed in newer versions of Serato, and we need some updated guidance on the XML needed for this.
I've tried in both Normal and Hybrid midi modes (from the SC3900 manual I don't think setting the lighting should work in Hybrid mode).

How do I set behaviour based on the value of a control? On the SC3900 there are a couple of buttons that both use the same control but send a different value. I want to use loop_length_double when one value is sent and loop_length_half when a different value is sent, e.g. (this doesn't work because I don't know how the condition should be set):
<control channel="5" event_type="Control Change" control="85">
<case>
<condition operator="equal" cmp_value="127" />
<userio event="click">
<loop_length_half deck_set="Default" deck_id="0" slot_id="0">
<translation action_on="press" behaviour="explicit"/>
</loop_length_half>
</userio>
</case>
<case>
<condition operator="equal" cmp_value="0" />
<userio event="click">
<loop_length_double deck_set="Default" deck_id="0" slot_id="0">
<translation action_on="press" behaviour="explicit"/>
</loop_length_double>
</userio>
</case>
</control>
djeyewater 2:50 PM - 16 November, 2019
An answer to part of my previous post, plus some other XML Midi mapping info people may find useful, and some more questions:

Setting behaviour based on value of control
I couldn't actually find a proper way of doing this, however in the case I needed it for, the values sent are 127 and 0. It seems these equate to an action_on value of press and release. So my XML for this looks like so:

 1. <!-- Loop length -->
 2.    <control channel="5" event_type="Control Change" control="85">
 3.        <userio event="click" >
 4.            <loop_length_double deck_set="Default" deck_id="0" slot_id="0">
 5.                <translation action_on="release" behaviour="explicit" />
 6.            </loop_length_double>
 7.            <loop_length_half deck_set="Default" deck_id="0" slot_id="0">
 8.                <translation action_on="press" behaviour="explicit" />
 9.            </loop_length_half>
10.        </userio>
11.    </control>


Lighting output
Haven't looked any further into the lighting.

Modifiers in current Serato
Still don't know how to get modifiers working in 2.1.1 and later, so I'm just sticking with 2.1.0 and will have to avoid buying any newer hardware that is only supported in later versions of Serato.

Moving Loop in / Loop out
For the SC2900 (or any other controller with a jogwheel) this can be done by chaining loop_in / loop_out with dvs_loop_adjust_enabled:
 1. <control channel="5" event_type="Note On" control="57">
 2.         <case>
 3.             <condition>
 4.                 <modifier_2 deck_set="Default" deck_id="0" slot_id="0" operator="equal" cmp_value="off"/>
 5.             </condition>
 6.             <userio event="click">
 7.                 <loop_out deck_set="Default" deck_id="0" slot_id="0">
 8.                     <translation action_on="press" behaviour="explicit"/>
 9.                 </loop_out>
10.             </userio>
11.         </case>
12.         <!-- Loop out adjust (see Loop in adjust note) -->
13.         <case>
14.             <condition>
15.                 <modifier_2 deck_set="Default" deck_id="0" slot_id="0" operator="equal" cmp_value="on"/>
16.             </condition>
17.             <userio event="click">
18.                 <loop_out deck_set="Default" deck_id="0" slot_id="0">
19.                     <translation action_on="press" behaviour="explicit"/>
20.                 </loop_out>
21.                 <dvs_loop_adjust_enabled deck_set="Default" deck_id="0" slot_id="0">
22.                     <translation action_on="press" behaviour="toggle" />
23.                 </dvs_loop_adjust_enabled>
24.             </userio>
25.         </case>
26.     </control>


However, there are two issues here I need help with:

1. dvs_loop_adjust_enabled should be on when loop trim is activated, and then disabled when you are finished. However, I can't see any way to explictly turn on or off dvs_loop_adjust_enabled. Using toggle relies on you having to use the same key combination to end the loop edit as you used to start it.
I have tried a static behaviour with static_values of 0,1,127,255,on,off,enabled,disabled - none of which worked for turning dvs_loop_adjust_enabled on or off. There does not appear to be an alternative dvs_loop_adjust_disabled either.
So, does anyone know how to turn dvs_loop_adjust_enabled on or off instead of just using toggle?

2. I don't know how to adjust the loop without using dvs_loop_adjust_enabled. If I want to adjust the loop start / end points using a button or knob instead of the jogwheel, how would I do this? I've tried both loop_start_point and loop_in_edit_mode with no success. Basically I need to know what the xml equivalent is of pressing the left / right arrow keys on the keyboard while in loop start / end point edit mode.

As a side-note, it seems that if you use a <case> then you can't combine that with <userio>s outside the <case>. For example, the above XML would be better written as the following, but it doesn't work:

 1. <!-- Loop out -->
 2.    <control channel="5" event_type="Note On" control="57">
 3.            <userio event="click">
 4.                <loop_out deck_set="Default" deck_id="0" slot_id="0">
 5.                    <translation action_on="press" behaviour="explicit"/>
 6.                </loop_out>
 7.            </userio>
 8.        <!-- Loop out adjust (see Loop in adjust note) -->
 9.        <case>
10.            <condition>
11.                <modifier_2 deck_set="Default" deck_id="0" slot_id="0" operator="equal" cmp_value="on"/>
12.            </condition>
13.            <userio event="click">
14.                <dvs_loop_adjust_enabled deck_set="Default" deck_id="0" slot_id="0">
15.                    <translation action_on="press" behaviour="toggle" />
16.                </dvs_loop_adjust_enabled>
17.            </userio>
18.        </case>
19.    </control>


Long comment bug
There appears to be a bug in Serato when you load an XML that contains a long comment. It seems it doesn't mind if the long comment has no more comments after it, but if it does, then Serato will just crash. The solution in this case is to add your comment as an attribute to the relevant XML element, e.g. <case comment="Some long comment here...">


Using a toggle modifier
Normally with a modifier you press the modifier button at the same time as the key you want to perform the alternate action for. If instead you want a toggle modifier, so that you press the modifier, then any key press after that is treated as if the modifier is pressed, you can set the modifier behaviour to toggle:
1. <control channel="5" event_type="Note On" control="16">
2.         <userio event="click">
3.             <modifier_3 deck_set="Default" deck_id="0" slot_id="0">
4.                 <translation action_on="press" behaviour="toggle"/>
5.             </modifier_3>
6.         </userio>
7.     </control>


Library messed up when _Serato_ dir is a symlink (in Windows)
If your music files are on a drive other than C: and you move the _Serato_ dir to another drive and then create a symlink pointing to it as %userprofile%\Music\_Serato_, for every file in your music library Serato will add another with the same filepath but C:\ as the drive instead of the actual drive letter the files are loaded on. Very weird behaviour.
djeyewater 9:02 PM - 16 November, 2019
Adjusting loop in / out
To answer the second part of my question about adjusting loop in / out position without using the platter, you can do this using beat_jump:
 1. <!-- Loop in adjust -->
 2. <case>
 3.     <condition>
 4.         <loop_in_edit_mode deck_set="Default" deck_id="0" slot_id="0" operator="equal" cmp_value="on"/>
 5.     </condition>
 6.     <userio event="click" comment="Note there is an element beat_jump_step but the value you set it to seems to make no difference.">
 7.         <beat_jump deck_set="Default" deck_id="0" slot_id="0">
 8.             <translation action_on="release" behaviour="static" static_value="forward"/>
 9.             <!-- Note setting a curve here seems to make no difference to the adjustment step / speed -->
10.         </beat_jump>
11.         <beat_jump deck_set="Default" deck_id="0" slot_id="0">
12.             <translation action_on="press" behaviour="static" static_value="backward"/>
13.         </beat_jump>
14.     </userio>
15. </case>

The weird thing is that I‘m sure I tried this previously, and it jumped back to the previous beat. (So the step was far too large to be used as an adjustment). Now when I’m using it, it is only moving a small step. The step isn’t as small as single arrow key press on the keyboard gives you, but it is good enough. It seems you should be able to adjust the size of the step via beat_jump_step but I tried various values for that and it made no difference.

OR conditions
As far as I can see, while you can do AND conditions (just put multiple items inside a <condition> block), it is not possible to do OR conditions? This means I have to have two separate <case>s for loop_in_edit_mode and loop_out_edit_mode that are exactly the same apart from the <condition>.