HOW TO work with Modifiers in the MIDI Mapping XML

Testing more on other controller, my assumption that setting the modifier1-6 states happens automatically when selecting PadModes on decks or that the DeckSelect action is altering the states of modifier5/6 is false. The modifier states do not get populated by simply selecting a mode through the built-in MIDI command. There’s some other logic & mechanism for setting these modifier states, which will need to be figured out. It’s most likely not something built in the program code, but within the controller mapping configuration files.

Yet, for editing on overmapping of already mapped controllers with already populated modifier states from the stock mapping, the instructions above remain fully valid and work well. Evaluating “conditions” works seamlessly in any case.

Until I figure out how to set states, I will not be able to map the original Mixtour or the X1 MK3 that I have for 4 deck controls, unfortunately. If I know how to rise modifiers and their states through the XML/JSON, layers of control will be very easy to be implemented for virtually any controller out there. And I will also write detailed instructions for others to benefit too.

@Slak_Jaw, input/hints from the Dev team for how to rise modifiers and states through the JSON/XML will be very welcome!

1 Like

Hi @Kaloyan, we do not officially support the editing/modification of XML files, for obvious reasons, so I’m afraid you’ll have to figure this out on your own. Wish I could be of more help!

1 Like

Customers have to go through this troubles :pensive:

Hi @hardbea7, thanks for the feedback. The dev team is aware of user demand for more powerful MIDI modifiers. Please cast your vote in the linked topic below to show support for this feature and to help the team prioritize future djay enhancements. Thanks!

Regardless if the XML editing is supported, or not, the functionality that we are asking for is here. It’s not about “more powerful”. It already is very powerful and completely sufficient. We just don’t have (or know) a way to set modifier states. But the application is very close to provide a complete Out Of the Box Support.

Going over many mapping files, I see this:

  • Most controller mappings use “modifier1-4” for the PadMode state of the 4 decks, but not all.
  • Most controller mappings use “modifier5-6” to track if Deck1 or 3 is selected on the left side in modifier5; and if Deck 2/4 is selected on the right side, but not all.
  • Mixtour is using modifier1 for tracking if the “FX” button is pressed to do the conditions logic for when FX mode is selected and the FIlter know would become FX1 parameter control.
  • RANE Performer mapping is build with a more meaningful names of the modifieres: “PadMode1”/“PadMode2”/ertc for the selected pad mode of the 4 decks; The selected decks are tracked as “LeftDeck1”; “RightDeck2”; “LeftDeck3”; “RightDeck4” with values of 0/1 indicating which is selected, instead of the modifier5 & 6 approach across the majority of the mappings.
  • the PadMode values in modifier1-4 also varies between the different controller mappings.
  • There already is dual conditions support with the keywords “AND” and “&&amp”;
  • There already are equal “==” and does not equal “!=” operands.

While there are similarities in how controller mappings are implemented, there’s apparently no strict/fixed convention. The names differ, the values too. Yet, the approach is very similar across the controllers and in my opinion, a very nice way for “modifiers” functionality - I really like it, and it’s already here and working. Very little extra is needed to make it available to us.

If only selecting a PadMode through the MIDI command would rise/alter a modifier state, it would be great, and we can do anything with mappings. There are 21 distinct MIDI commands for Pad Mode Select. 21 modes per deck! They are already implemented and all it would take is to also set a unique number value in a correspondingly named Modifier name (similar to modifier1-4, or PadMode1-4) upon selection. Once we have this, we can do virtually ANYTHING within our mappings and have all the needed layers available to map anything. Of course, as the names modifier1-6 are already in use across the legacy mappings, the names have to be different but e.g. “DeckPadMode1-4” is probably not in use by any controller yet, and available for an OOB use.

Of course, I realize that due to the variations of the existing mappings, backward compatibility has to be preserved. There are about 183 stock mapping files in the application as Nov 2024. IMO, it would be an unnecessary overkill and unneeded to make them consistent. The much higher value for us would be to just have ability to work fully with them, regardless of the naming conventions used historically.

Please consider enhancing the per-deck “Select Pad Mode” MIDI action to also set a state in a modifier name “DeckPadMode1-4” (or similar), that we can use as condition for building advanced multi-layer mappings. We can do everything with our mappings if the app just does this small thing.

4 Likes

Thanks for the detailed investigation and explanation @Kaloyan. Great suggestion! I have already shared this with our dev team for consideration.

2 Likes

My man, (or woman), you’re killing it, good job with the reverse engineering . I also figured out the multi layer mapping I tried to let people know about it. I uploaded a mapping for the DDJ-FLX4. The extra layer, it blew my mind, but I just stumbled upon it in the mapping menu inside Djay on macOS, and never went through the XML and figured that part out. Now granted, I’ve gone through the XML a lot… I just can’t figure any part of itr out., I’m comparing them side-by-side in BBedit, but nothings clickin lol.

I do a s**t job of trying to explaining how to do it, but you definitely nailed it.
If anyone’s curious, this second layer of shifting also works on pioneer gear, at least the DDJ-1000 in the DDJ-FLX4. On my profile I’ve uploaded a mapping for The DDJ-FLX4 that was the extra layer of shift. It gives you control of four channels. It uses the smart fader (SF) button as the second shift.
so SF + play button on deck 1 = Play Deck 3. Same with many of the buttons on there…

It is missing the smart color effects on each of the channels, that feature didn’t arrive at the time that I made edited that that originally came from @Michael_Wisniewski . Which is my base XML and I started editing.

. And for the life of me, I can’t figure out : 1) what the command is on the new mapping/XML that I could copy and paste into my current mapping that would give me that functionality, but it’s all right. I can rebuild it and make it better.
2) (this may be a slick draw thing I may need to make another thread) I’m using my gain knob and my three EQ knobs to change the 4 Nueral mix EQ’s.
vocal w/ gain
harmonic w/ high eq
bass w/ mid eq
drums w/ low eq
But whenever I move the high EQ, the harmonic control, the bass is also controlled at the same time, which is not supposed to happen, because the bass, just like the vocal and drum EQ knobs are supposed to be individually controlled. When I move the mid eq, the base moves independently.
So if I turn the base all the way down and it stays down when I move the harmonic EQ, the bass jumps up to where the harmonic EQ knob is.
It does this when I map the activity "Neural Mix EQ (2) " under the neural mix 4 cghannelheader in the mapping menu, and, when I’m map the activity "Neural Mix EQ (4ch Harmonic) " I can’t figure out how to separate and keep the bass from being controlled with the harmonic, which would be expected if it was three channel separation. This may be on their end, because for sure previous versions were not like this, but I can’t remember when the change happened. but it’s like that on both of my controllers, and any other gear that I’ve mapped.

I love nerd out on this kind of stuff, and then he said it is exciting as this gives you so many more possibilities it’s wild.
Now it’s not your equipment that will hold you back. It’s your dedication

Edited some of my wording because it’s late. I also just now saw where you added the FX control slot.
I’ve got some more studying to do,
Thank you for documenting all that in an understandable way!!!

Cheers @Patch_ed !

There’s actually an easier way to Duplicate built-in commands, which are already pre-conditioned and then apply a custom “(SHIFT)” action to them.

The way the Custom “(SHIFT)” works in djay’s XML is the presence of these two lines to a command’s “dict” section

			<key>modifier</key>
			<true/>

at they go to the very end of a section.

To illustrate, here is a stock dict block that controls FX Wet/Dry for Deck1 on a knob:

		<dict>
			<key>condition</key>
			<string>modifier5 == 0</string>
			<key>keyPath</key>
			<string>turntable1.fx1WetDryValue</string>
			<key>midiChannel</key>
			<integer>8</integer>
			<key>midiData</key>
			<integer>0</integer>
			<key>midiMessageType</key>
			<integer>3</integer>
		</dict>

And below is the (SHIFT) action for the same knob (8/0/3), that controls the FX1 Parameter:

		<dict>
			<key>condition</key>
			<string>modifier5 == 0</string>
			<key>keyPath</key>
			<string>turntable1.fx1ParameterValue</string>
			<key>midiChannel</key>
			<integer>8</integer>
			<key>midiData</key>
			<integer>0</integer>
			<key>midiMessageType</key>
			<integer>3</integer>
			<key>modifier</key>
			<true/>
		</dict>

Both have the “modifier5 == 0” condition filter, which takes care that it only works when Deck1 is selected, and not for Deck3. The same 8/0/3 message doing different things with and w/o (SHIFT).

So practically, to make the same knob under a “condition”, capable of controlling a second action for the same deck or a PadMode through a Custom Shift (e.g. your SF button), you cannot just MIDI learn with (SHIFT) + control from the UI, as it will start with the empty entry w/o “condition” filter. It won’t respect the Deck1/3 or the PadMode selection. Instead, all you need to do is to “Duplicate” in the XML directly by copy & pasting text from the dict to the /dict tags, and add the “modifier /true” thing at the end, right before the closing “/dict”. This way, you preseve the original condition string and have a (SHIFT) action like you can do through the UI, but this time it inherits the filters filters.

I somewhat think that it is easier to just duplicate the command in the XML and add a simple:

			<key>modifier</key>
			<true/>

which is always the same, and makes it a (SHIFT) action, instead of “reinventing” condition strings for a duplication done through the UI, and without the proper condition. This is somewhat easier and more straight forward and you don’t need to bother tracking the selected deck or pad mode condition filtering (which you can’t from the UI yet), as it’s already inherited in the cloned entry from the start.

The approach is fully appliable if you want to add a Custom (SHIFT) action to the PadModes. If you go through the UI and create a set of (SHIFT) actions by MIDI learn, they wont have a PadMode filter, and out-of the-box you will have just one set of (SHIFT) mapping for all the pads across all PadModes. What a waste, eh? Instead of getting a full 8x8=64 more buttons on the FLX4 to set a (SHIFT) action to, you only get 8, which are global regardless of the selected PadModes. Blah, I wouldn’t be happy. All is more :slight_smile:
Instead, just go to the XML & locate the PadMode definition in the XML for a certain PadMode. The names of the commands mean a lot, and you can easily navigate. Once you identify the PadMode records, just copy & paste all the 8 dict sections for all 8 buttons of the PadMode at once; append a modifier /true set of tags at the end of each of the dict blocks in the pasted set, and you’re done. And in my opinion, that’s a fairly quick thing to do. Then go back to the UI, and you have a set of 8 properly filtered (SHIFT) entries for each of the 8 pads in the pad mode which are assignable to do different things. And you can repeat this for every PadModes, which would give you a total of 64 extra (SHIFT) controls - one for each of the PadModes.

HTH,
Kal (and I’m a dude, BTW :wink: )

2 Likes

Hi @Kaloyan , you’re really rulling it!!! Very useful information here! Well, here’s my problem.

Suppose I don’t want to use the Sync button as it is and, instead, i’d like to switch between decks 1 and 3. I’m in an original 2 deck controller.

How do I do that on Djay? I tried to map it like “Select deck 3” on the software , for example, but when I tried to map the other funcions like “play/pause”, they where still assinged to deck1, the software didn’t recognize the Sync as a modifier. In other words, the software didn’t open a new button to be mapped, only the already mapped button appeared.

Can you help?

1 Like

Hi, @Kaloyan , just to be more clear…

I expected that, when I hit the Sync button for the 1st time, it would be lit and Deck 3 would be active (like many controllers like the DDJ REV1 does, but in their specific buttons 1/3 or 2/4). Pressing it form the secont time it would be off and we’re back to Deck 1.

Instead, it was always off and, because of that, I’d always have to press Sync + Play/pause, if I wanted to Play/pause the Deck 3.

So, summarizing: Sync button would be my Deck 1/3 button. When I press it, it should be lit and select deck 3 (working more or less like a modifier, in my oppinion). After that, when I press other buttons, like play/pause, Djay should open a new mapping note for me to map (with no need to press the Sync again).

Do you know any way to map this button to behave this way I described?

Hi @Carlos_Alexandre_Cam,

I’ve checked the REV1 mapping and you do have the selected deck state in:

			<string>modifier1 == 0</string> - Deck 1 active
			<string>modifier1 == 1</string> - Deck 3 active

			<string>modifier2 == 0</string> - Deck 2 active
			<string>modifier2 == 1</string> - Deck 4 active

This is used to control the FX mappings, as the unit is designed for Serato primarily, and Serato has 2 assignable FX units. It’s common for the djay mappings to use modifiers for FX controls in 4 deck mappings to make the controller handling the FX for Deck1/3 or respectively 2/4 when they are selected. You can reuse these conditions for your needs.

Your overmapping layer has to be created for both decks 1/3 & 2/4 in pairs. When you work on Deck 1, the Custom Shift would give you control over Deck 3. You need to insert <string>modifier1 == 0</string> to these to filter out that Deck1 is your context. Then you need to switch to Deck 3, and overmap it for Deck1 controlls, in which case you need to manually insert the condition <string>modifier1 == 1</string>, so that it applies only when Deck 3 is selected. The same goes for Deck 2/4, with the respective states being defined.

As per what’s lit and what not - the Custom Shift does not support visual feedback - you will be in the “dark” here.

You say that you want to use the “SYNC” button as a Custom Shift. That just adds a <key>modifier</key> to your sections, wherever you overmap. As an idea, you may still keep your SYNC button, and create your Custom Shift as “Shift + SYNC” (it should have unique MIDI msg). Or vice-versa - keep the SYNC available as Shift+Sync, and have the Custom Shift as a top-level control.

Happy mapping!

Hi friends, is there a way to lock custom SHIFT button on active? in MIDI learn there is no possibility to select the type of function of the shift button. It would be a great way to create at least two banks of functions in the controller without pad mode

1 Like

Works if you add it to a rotary, have done it on my K2 with led active when shift is on, but would also like to know if there is way with only a button

1 Like

Hi @Kaloyan . Thank you very much for your time and patience to explain your findings.

I’ve mapped a few funcions using the sync button as a shift to control the decks 3 and 4. Just the basic ones, like play, cue, deck volume, phones cue. I’d only use this for scratching on decks 3 and 4. I have some files full of scratch sounds and normally load them on decks 3 and 4 to have some fun in between songs.

I was able to use this way, but it’s far from ideal. Specially because I had to map the jog wheels in a way that I have to scratch both decks 1/3 or 2/4 at the same time. And sometimes, if I am in a cue point in deck 1 and want to scratch on deck 3, I end loosing the cue point in deck 1. Of course it’s only a matter of hitting shift+cue on deck 1, but it’s not ideal.

Anyway, let’s hope Algoriddim improves the midi mapping. It would open a lot of possibilities

Glad it helps!

You may wish to try if Selected Deck won’t give you temp scratching for a background deck. “Selected Deck” target only works on a single deck, and may not be ideal, but still.

have you used the XML conditions when building your mapping? I’ll be happy to hear if these instructions are of an actual good use to people :slight_smile:

@giu_gi & @AKB

I’ve tried hacking it, and in my test, the app ignores the toggle directive in the XML section for the Custom SHIFT.

This is how I did it:

	<dict>
			<key>buttonMode</key>
			<string>toggle</string>
			<key>keyPath</key>
			<string>application.modifier</string>

But no go, unfortunetely. It just doesn’t toggle :slight_smile:

At least it doesn’t break the XML and the app loads the mapping at startup. There has to be special handling of this use case in the app code to be so disabled. It’s not only the UI which prevents setting it. :slight_smile:

Give it a shot too, if you want. The “buttonMode” directive sits below the “dict” and above the firt “key”. Right at the start.

Hi, @Kaloyan , very sorry for the late answer.

I haven’t tried working directly on the XML for lacking of time, but some ideas you gave were already very useful.

I stopped working in a 2 deck controller for now and started on a DDJ WEGO2 (which controls 4 decks). This controller doesn’t offer many pad modes, but I was able to map many cool features using the SYNC button as a 2nd SHIFT for it. For example, SYNC + CTRL A = Neural Mix Acapella; SYNC+FX1 = Backspin; SYNC+LOAD = Toggle Quantize on/off; SYNC+Phone Cue = Time remaining/elapsed and so on.

If I have some time in the near future, I’ll definitivelly try some XML editing… I love this kind of new experiences… :slight_smile:

Hi @Kaloyan , here’s a question for you. Imagine I’m working with a Herculea Inpulse 200, which is a 2 deck controller.

If i set one of the 4 available pad modes (eg: the sampler mode) for working on the basic functions of decks 3 and 4 (play, cue, and maybe one or two FX), this pad mode is obviously working as a modifier.

Do you think I could also map the volume, scratch and other controls directly on the XML file? It should work like pad mode sampler = control of deck 3 (or 4). Then, in the XML file, I could map the other basic functions accordingly, introducing the command lines you mentioned before.

I only use the decks 3 and 4 like “scratch decks”: I load some files with scratch sounds and play with them, so I don’t really need all the other functions…

Do you think this is feasible?

Regards, Carlos Alexandre

IS it possible that you be kind enough to share the Request for MIDI Mapping Matrix for djay Pro

Specifically, I would appreciate the following details for each function:

  1. Function: The name of the function (e.g., “FX 1 Instant”, “Play/Pause Deck 1”, “Filter Knob Deck 1”).
  2. MIDI Message Type: The type of MIDI message (e.g., “Note On”, “Control Change”, “Note Off”, “Pitch Bend”).
  3. MIDI Value: The corresponding MIDI note number or control change value (e.g., “Note 36”, “CC 7”).
  4. Description: A brief description of the function or what it controls (e.g., “Triggers FX 1 instantly”, “Adjusts volume for Deck 1”).

For example, the matrix could look like this:

Function MIDI Message Type MIDI Value Description
FX 1 Instant Note On Note 1 Activates FX 1 instantly
Play/Pause Deck 1 Note On Note 36 Trigger play/pause action for Deck 1
Filter Knob Deck 1 CC CC 20 Adjust filter frequency for Deck 1
Volume Knob Deck 1 CC CC 7 Adjust volume for Deck 1

There is a catalogue of the midi actions here

Maybe not uptodate, but it’s here.

I would not put time and energy in describing the list of midi actions.