Screenshots |
Links |
Electrobel |
RSS Feed |
Hosted by |
MIDI Controller XML files allow you to create very creative and flexible
MIDI mappings for almost any MIDI controller.
The mappings do not limit you to just mapping Buttons, Sliders and Knobs to
certain actions, but they also allow mapping of various types of jog wheels,
as well as feedback through lighted buttons, leds, led strips, and even displays
and motor-driven jog wheels.
Mappings aren't limited to one action per control either. It is not very
hard to create tabs, which can be selected in a number of ways.
All device xml files are stored in the sub-folder devices in your
djDecks folder. (Usually c:\Program Files\djDecks\devices)
djDecks comes pre-installed with a number of device xml files for the controllers
supported by djDecks.
If you want to edit one of the default mappings, it is recommended that you copy the file
and rename it, to ensure that your work is not lost when upgrading djDecks.
To bind a mapping to a certain device, open djDecks and go to Options->General.
There you can select MIDI and press XML config.
Now select the midi device you want to use in the top list, and select the
device XML file you want to use in the drop-down.
Finally click Connect, and your device should be ready.
Although these xml files can't be created automatically or through midi learn yet,
you can use the Skin Helper utility
to generate the input, output and input_output objects and look up the correct definitions.
In combination with MIDI-OX this makes it a lot easier to create these mappings.
<DEVICE>
<NAME>Mapping Name</NAME>
<TYPE>MIDI</TYPE>
<DESCRIPTOR>
...
</DESCRIPTOR>
<SCRIPT>
...
</SCRIPT>
<CHARACTER-MAPPING>
...
</CHARACTER-MAPPING>
<INPUT>
...
</INPUT>
<OUTPUT>
...
</OUTPUT>
<INPUT_OUTPUT>
...
</INPUT_OUTPUT>
<TABS>
<TAB>
...
</TAB>
...
</TABS>
</DEVICE>
Each mapping must have a Name, Type and Descriptor.
The name can be any name for your mapping, type is Midi for now, but could be extended
to Keyboard and HID mappings in the future.
The Descriptor describes how the device can be found (it's midi name) so that a list of
compatible device mappings can be shown when selecting a device. (This is not used yet)
Next there can be one or more embedded scripts. These are optional.
Character-mappings can be defined for devices with character displays or led strips. These are also optional.
Input objects will respond to input from the controller.
Output objects will send data to the controller (such as led status)
Input_Output objects are a combination of input and output object. This is
just a convenient way of creating both an input and output object that share
the same midi messages and mapping in djDecks. (For example lighted buttons)
Input and Output objects can also be grouped in TAB sections, and different TAB sections
can be grouped in a TABS section. Only one TAB section will be active for each TABS section at a time.
<DESCRIPTOR>
<MANUFACTURER>Stanton</MANUFACTURER>
<MODEL>SCS.3d</MODEL>
<input_endpoint_name>Stanton SCS.3d</input_endpoint_name>
<output_endpoint_name>Stanton SCS.3d</output_endpoint_name>
</DESCRIPTOR>
The input and output endpoint name should be set to the MIDI Device name, as shown in the device list.
These fields are not used yet.
<INPUT>
<BYTES_DOWN>9P 6D 01</BYTES_DOWN>
<BYTES_UP>8P 6D 00</BYTES_UP>
<TYPE>Button</TYPE>
<VALUE>Pause</VALUE>
<VALUESPECIFIER></VALUESPECIFIER>
</INPUT>
There are many ways to define an input object. The correct way will depend on
the controller, the config, and the action you want to assign to it.
Each input object has 2 parts, one part defining the data coming from the controller
that the object should respond to, and another part defining the action that should be taken.
An optional third part can define a condition that needs to be met before the object will take effect.
To find out which byte values a controller sends, it is recommended to install and use MIDI-OX.
* Deck Selection
There are several ways to select which deck an object will affect, and it is possible for one effect
to control multiple decks, which makes it easier to map, since you don't need a different object for the
play button on the left side of the controller and the play button on the right side of the controller for example.
<PLAYER>0</PLAYER>
The object will control the object on the player defined in the PLAYER field (starting from 0)
<BYTES_DOWN>90 6D 01</BYTES_DOWN>
<BYTES2_DOWN>90 6E 01</BYTES2_DOWN>
When the bytes defined in bytes_down are received, the object will control deck 1, when
the bytes defined in bytes2_down are received, the object will control deck 2.
Of course the same counts for bytes_up, and it can be used for deck 3 and 4 as well.
<BYTES_DOWN>9P 6D 01</BYTES_DOWN>
On some controller, the MIDI channel number is used to define the deck. This means messages sent from
the controller will start with 90, 80 or B0 for deck 1, and 91, 81, or B1 for deck 2.
In this case you can simply replace the 0 with P to let djDecks know that the deck number should be taken
from the channel number.
Following is a list of types, each with the possible uses.
* Button
A button usually sends a message when it's pressed, and another one when it's released.
Usually djDecks will take care of the correct action to be taken on press and release, but you
can also force an action to happen on press or release by only defining 'up' or 'down' bytes.
Bytes_Down specifies the byte sequence (in hexadecimal) that the controller sends when a button is pressed.
Bytes_Up specifies the byte sequence that the controller sends when the button is released.
Note on midi messages start with 90, Note off midi messages start with 80, CC messages start with B0.
Some controllers use note on messages for key press, and note off messages for key release.
Other controllers use note on messages for both, but with a different value (usually 7F for key press, and 00 for key release)
Check MIDI-OX, or the documentation of your controller to find the messages sent by your controller.
* Slider
A slider will send a message with the absolute position of the slider whenever it moves.
Slider is usually also the type you should use for equalizer knobs for example, as they work in the same way.
<BYTES>B0 47 VV</BYTES>
VV at the end indicates that the last byte will hold the value of the slider.
If you look in MIDI-OX, you will see this moving from 00 to 7F when moving the slider from bottom to top.
<BYTES>EP VL VH</BYTES>
Some controllers such as the Denon HC-4500 use 2 bytes to get a higher accuracy for the pitch slider.
In this case VL indicates the 'low' byte, and VH indicates the 'high' byte.
* Jog Wheel
Jog Wheels use a variety of methods to send their data.
-Some controllers send the speed of the jog wheel around the center. Values greater than 3F indicate forward movement. Values smaller than 3F indicate backward movement.
<BYTES>BP 01 VS</BYTES>
VS indicates that it is a signed (both positive and negative) value.
-Some controllers are increasing from 01 for forward movement, and decreasing from 7F for backward movement.
<BYTES>BP 01 VT</BYTES>
-Some controllers send one message for forward movement, and another for backward movement
<BYTES>BP 01 VV</BYTES>
<BYTES>BP 02 VN</BYTES>
VV indicates positive (forward) values, VN indicates negative (backward) values.
Because different jog wheels have different accuracy and sensitivity, the jog wheels may be too sensitive, or hardly have any effect.
To fix this, you can use SCALE to scale the values.
<SCALE>10</SCALE>
Use values greater than one if they aren't sensitive enough, or
<SCALE>0.05</SCALE>
Values smaller than one if they are too sensitive.
Some controllers have touch sensitive jog wheels. This means that they send a message
when the jog wheel is touched, and another message when the jog wheel is released.
Usually this messages are similar to regular buttons. Use a separate object for this, with value JogWheelTouch
The jog wheel object itself should also have touch in the valuespecifier.
Jog Wheels are usually used either for scratching or for pitch bending.
For scratching, use value Pitch and optionally valuespecifier touch if they are touch sensitive.
For pitch bending, use value PitchBend
To provide both pitch bending and scratching, use a tabs section with 2 tabs.
Name one jog_bend and the other jog_scratch
If the controller has a button to switch between bend and scratch mode, you can include it in the tabs.
In the jog_bend tab, the button will use TabSelect and jog_scratch, in jog_scratch, the button will use TabSelect and jog_bend.
An output object looks identical to a input object, but will send data to the controller rather than receiving it.
* Button
When type Button is selected, djDecks will send the bytes in bytes_down when the object is active,
and the bytes in bytes_up when the object is inactive.
Buttons can also flash to indicate that a button can be used. The VCI-100 mapping uses this extensively to show
which buttons have a special function while another button is pressed.
<flash_length>1200</flash_length>
<flash_offset>0</flash_offset>
<flash_ratio>0.25</flash_ratio>
Flash_Length indicates the time of one cycle in millseconds, in this case the led will flash every 1.2 seconds.
Flash_Offset sets an offset for when this led will start flashing. Also in milliseconds. When you have multiple leds, you can
increase this for each led (for example, 0, 200, 400, 600 and 800) to create a led cycle.
Flash_Ratio indicates how long the time will be on. 0.25 means one fourth of the cycle, or 300 milliseconds in this case.
* Slider
Slider output will usually be used either for motorized faders, or for led strips such as vu-meters.
To simply send a value between 00 and 7F to the controller, use it in the same way as Slider input objects:
<BYTES>BP 01 VV</BYTES>
Some led strips require only a couple of values to select which leds will be turned on.
For example, your controller may expect BP 01 02, BP 01 03, BP 01 04, BP 01 05 to light up 1,2,3 or 4 leds.
In this case, you need a character mapping, mapping a percentage to a number. For the example, it would look like this:
<character-mapping>
<name>4-segment mapping</name>
<shortcut>A</shortcut>
<map><char>00</char><val>02</val></map>
<map><char>25</char><val>03</val></map>
<map><char>50</char><val>04</val></map>
<map><char>75</char><val>05</val></map>
</character-mapping>
You can then use the following output:
<BYTES>BP 01 XA</BYTES>
X means it will reference a character map, A is the shortcut for the character map.
Note that char is ranged between 0 and 100, and val is the value to send in decimal (so if the documentation mentions it in hexadecimal, like 0A, you have to use 10 as value)
Some controllers can also turn on or off each led individually, for example, a controller might expect BP 02 00 to turn the first led off, and BP 02 7F to turn it on, BP 03 00/BP 04 7F for the second led, ...
In this case, use bytes_up and bytes_down instead of bytes:
<BYTES_DOWN>BP XA 7F</BYTES_DOWN><BYTES_UP>BP XA 00</BYTES_UP>
* Jog Wheel
TODO
* Text and other characters
TODO
An input_output buttons looks identical to an input and an output object, but combines the two functions.
Most controllers accept the same bytes to toggle the state of a lighted button as the bytes they
send when the button is pressed.
In this case, an input_output object is very easy to use, since you just define it in the same way
as you would a regular input button, and the led under the button will work without further configuration.
Note that this is not the case for all controllers, in that case, both an input and and output object have to
be defined for one button.
<TABS>
<TAB>
<NAME>tab1</NAME>
<DEFAULT>yes</DEFAULT>
<INPUT>
...
</INPUT>
</TAB>
<TAB>
<NAME>tab2</NAME>
<DEFAULT>no</DEFAULT>
<INPUT>
...
</INPUT>
</TAB>
</TABS>
This is an example of one TABS section. There can be more than one TABS section in one file.
Each TABS section has one or more TAB sections, of which one is active at a time.
It is recommended that the tab names are unique for the entire file.
To select a tab when a button is pressed, use the TabSelect value in an input object.
<TYPE>Button</TYPE>
<VALUE>TabSelect</VALUE>
<VALUESPECIFIER>tab2</VALUESPECIFIER>
Also note that this object can be located both outside and inside a tab.
So you could have 4 buttons, each of which selects a different tab. In this case you would place the
TabSelect objects outside the Tabs.
You could also have one button, that cycles through different tabs. In this case, you would have a
TabSelect button in each Tab. In tab1, there is one which switches to tab2, and in tab2 there is one which
switches back to tab1. (or to tab3, ...)
To create a SHIFT-function, you can use tabs which are only selected while a button is pressed.
Here's an example on how to do this:
<input>
<bytes_down>90 44 7F</bytes_down>
<type>Button</type>
<value>TabSelect</value>
<valuespecifier>sb_shift</valuespecifier>
</input>
<input>
<bytes_up>90 44 00</bytes_up>
<type>Button</type>
<value>TabSelect</value>
<valuespecifier>sb_default</valuespecifier>
</input>
An alternative SHIFT-function has also recently been added, by using TabSelectTemporary.
The difference is that you need only one object for the shift button, and that you don't have to remember the
previous or default tab. A jog wheel for instance, could be set to tab jog_bend or jog_scratch, but while
pressing a button, be used for jog_moveloop. When the button is no longer pressed, it would be best if the previous
tab was selected, instead of going back to a fixed tab.
<input>
<bytes_down>90 44 7F</bytes_down>
<bytes_up>90 44 00</bytes_up>
<type>Button</type>
<value>TabSelectTemporary</value>
<valuespecifier>sb_shift</valuespecifier>
</input>
Finally, there's also a variant on TabSelectTemporary which uses a time-out instead of a button-up.
After the selected time (in milliseconds) the previous tab will be selected again.
This could be used for a display which temporarily shows the action that was done, before returning to show it's
regular information.
<input>
<bytes_down>90 44 7F</bytes_down>
<bytes_up>90 44 00</bytes_up>
<type>Button</type>
<value>TabSelectTemporary</value>
<valuespecifier>sb_shift</valuespecifier>
<typevariable>3000</typevariable>
</input>
Scripts can be embedded inside a device XML. This allows you to distribute a single xml file
to share your mapping, even if it uses scripts.
For a description on how to create scripts, please read the scripting documentation.
<script>
<name>myscript.djscript</name>
<content>
//script commands go here
</content>
</script>
To use the scripts, simple use ExecuteScript as value, and the full script name as ValueSpecifier.
Character Mappings can be used for both displays and led strips/rings/...
For Led strips, it maps a number from 0 to 100 (percentage) to a value.
Most controllers use the MIDI protocol to communicate with the PC, but HID (Human Interface Device)
is another protocol that is used for some controllers.
The way it is used in DJ controllers is usually less structured than MIDI, so it is usually more difficult to map,
and will often require documentation from the manufacturer to get working properly.
HID devices usually send and receive packets of a fixed number of bytes, and one packet usually contains the state of
all buttons, sliders and other controls on the controller.
A useful utility to help you mapping your controller and seeing what your controller sends is SimpleHIDWrite, which can be downloaded from this site.
The first thing that is different is that the type in the descriptor should be HID instead of MIDI.
The other thing that is different is the way to describe the bytes from the controller.
The general format that can be used in bytes, bytes_up, bytes_down, ... for HID devices is:
BB bb nn 00 VV
BB: Byte number starting from 0 and formatted in hexadecimal
bb: bit number within this byte, starting from 0
nn: number of bits the message takes. Often 1 for buttons/leds, 8 or 16 for sliders/knobs
00: reserved, use 00 for now
VV: The value to use. 01 or 00 for single-bit buttons/leds, can be any of the regular VV/VN/... for sliders/knobs...
Example: Suppose that you see in SimpleHIDWrite that your controller sends the following bytes when you press and release a button:
00 80 00 00 00 00
00 00 00 00 00 00
(Ignore the first 00 before the tab in SimpleHIDWrite)
We see that when the button is pressed, the second byte changes to 80, and when the button is released, it changes to 00.
You can now use the windows calculator (in Programmer View in Windows 7) to convert this value from hexadecimal to binary.
This will show us that 80 in hexadecimal is 10000000 in binary.
Since we start counting from 0, we see that the byte number is 1 (second byte)
The bit number starts counting from 0 from the right, so we see that the bit is the 8th bit in the byte.
This gives us the following code:
<bytes_down>01 07 01 00 01</bytes_down><bytes_up>01 07 01 00 00</bytes_up>
It basically means to look at 1 bit, starting from the 8th bit in the 2nd byte.
When it becomes 01, we trigger a key press, when it becomes 00 again, we trigger a key release.
Example2:
00 00 54 00 00 00
Suppose that we see this third byte changing from 00 to FF when we move a slider from bottom to top.
The code to use it would be:
<bytes>02 00 08 00 VV</bytes>
So we are looking at the entire 3th byte (from bit 0, 8 bits long), and whenever this byte changes, our input object
will be triggered.
Some controllers send different reports for each side of the controller, and one byte indicates which side the report relates to.
In this case, you can extend the first 5 bytes with another 5 bytes defining where the player number is located. The format is the same as the first 5 bytes.
Example: Suppose that you see this in SimpleHIDWrite when pressing a button on the left side:
00 00 FF FF FF
00 00 7F FF FF
and this when pressing the same button on the right side:
00 01 FF FF FF
00 01 7F FF FF
In this case, the first byte indicates the player number. We also see that this controller reverses the button presses (bits are 1 when the button is not pressed, and 0 when the button is pressed)
We could now use the following xml:
<bytes_down>01 07 01 00 00 00 00 01 00 0P</bytes_down><bytes_up>01 07 01 00 01 00 00 01 00 0P</bytes_up>
So we use the first bit of the first byte and use it as the player number (0P).
Here are a few guidelines you can follow when creating your own midi mapping.
-Pitch Slider: There is an option to select between relative and absolute pitch slider.
To make it available in your xml, create 2 tabs named pitch_absolute and pitch_relative.
In pitch_absolute, you will likely use a Slider object, and in pitch_relative a SliderRelative object.
-Jog Wheel: There are different tabs that you can create to control what your jog wheel can do.
The recommended names for these tabs (also used by the DiscMode object) are jog_bend, jog_scratch,
jog_browse and jog_search.
djDecks (c)2003-2023 Adion