Custom MIDI Mapping: Hercules RMX 2 (0.1.3)

Sure thing, man! I’d appreciate the help!

What I know so far is that each controller gets its own mapping file (.midi.xml) and an optional script file (.js) to go with it. I’ve given the RMX2 both of these things because the scripting allows all kinds of crafty controls. Each time the mixer interacts with Mixxx, three bytes (we call them “status,” “control,” and “value”) are sent to the software. The mapping and script files just tell Mixxx what to do when these bytes are passed to it. In other words, we’re a translator for communication between software and hardware!

Just about every single button, knob, slider, and jog wheel on this mixer will send some sort of MIDI message in that format. The weird exceptions are:

  1. The volume knob on the Microphone and the volume knob next to the headphone output (no MIDI message is sent, so it’s likely hard-wired).
  2. The Mic On/Off, Mode, and Shift buttons (these send 19 bytes of data in addition to the 3, and the 3 bytes of data happen randomly).

To manipulate one of the controls that aren’t exceptional, you will first go to the .midi.xml file and declare that it’s going to be used. You can control it with the regular native Mixxx commands OR you can use your script to detail exactly what the button does:

    <control><!-- L Play using native command -->


    <control><!-- L Play using my script (a.k.a. PLAY + TURN ON LED -->

The advantage of going (the s are here) is that it’s easy and you don’t have to do any coding. The advantage with scripts is that you get more control. Version 0.1.4 is going to include LEDs with the buttons so that there’s more physical feedback. The Mic On/Off button and Shift buttons have their LEDs hard-wired, apparently, so at least that is less work for us!

But how did I get those numbers? And where’s control and value? Well when you go to your terminal and execute “mixxx --midiDebug” and press any buttons, the bytes will be printed out for you to copy/paste! Mixxx basically tells you what signal is sent to it when a button is pressed. Another useful tool is using “amidi -l” and “amidi -p hw:#,#,# -d” where #,#,# is whatever “amidi -l” printed out to just get the bytes and no MIxxx messages.

You’ll also find that a lot of the same dials and pads get multiple trios of bytes assigned to it depending on circumstances. The pad you hit in Sample mode, for example, will not be the same as the same one hit in Cue mode. It’s super convenient that we don’t have to detect the current mode, otherwise we’d have a lot of scripting to do!

To give you a breakdown of status/control/value, Status = the type (button/dial/wheel), Control = The particular one (WHICH jog wheel?), and value (WHICH way is it going? 0x7F or 0x01???) and the value for the jog wheels will also depend on speed so 6E is going pretty dang fast in one direction! Buttons are simpler; 0x7F if pressed, 0x00 if not. You’ll get the hang of it as you’re testing. It’s a good time here to tell you that means MIDI Control #, by the way. The value is automatically passed as a result of knowing these two bytes. Mixxx knows how to handle them, most of the time. For others, there’s scripting.

In scripting (which can be confusing!), there’s some basic housekeeping to take care of with the init() and shutdown() functions that I’ve defined. An ID is assigned to it, some important controls are properly set, etc. You will also see function “DJCRMX2(){}” which is definitely necessary – it allows the MIDI.XML file to access it using

<scriptfiles> <file filename="DJConsoleRMX2Scripts.js" functionprefix="DJCRMX2"/> </scriptfiles>

“DJCRMX2.scratching = [];” declares a global variable, in this case an array, in javascript. A global variable can be used by any function at any time. You don’t want every variable to be a global variable because if two functions are messing with it and you didn’t think of every possible outcome well then you’ve got an unpredictable shitstorm on your hands, so try to keep things separate by making the variables declared in your functions local. You do this by saying something like “var scratchingLocal = [];” and that way only the single function it was declared in can mess with it. Here, lemme show you the playButton function:

DJCRMX2.playButton = function (channel, control, value, status, group){
 if (value==0x7F && engine.getValue(group,"play") == 1)
 { // If currently playing and 7F hit, stop.
  midi.sendShortMsg(0x90,control,0x00); // Play LED Off
 else if(value==0x7F && engine.getValue(group,"play") == 0)

What we have here, line by line, is a function declaration, a test, then some controls, then another test if test #1 didn’t work, and controls for that. In the MIDI.XML file, we passed the play button’s control and status to the script, and Mixxx automatically sent in the value of the control, as well. We also tried to pass the channel ("[Channel1]") to the function but for some weird reason will show up in group and not channel. There’s probably a good reason for this. Anyway, it tests to see if we’re actively pressing the button down (0x7F) and also asks Mixxx if the song in Deck X is playing, where X depends on which button we hit (Deck A means Channel1, Deck B means Channel2! So it’s a smart function!). If we’re playing a song and hitting this button, this song has to stop. So we stop the song and turn the led off. The led is conveniently the same as the button. I said “control” instead of the specific button 0x## because, again, Deck X, smart function, ya savvy with me here?

If the song isn’t playing and the value is 0x7F then we need to get the train rollin’! Play the song and light up that button! The reason why we don’t test the value for 0x00 is because that is the release button, so we would have to hold the play button down for the entire song, and that’s silly. The button will send two sets of bytes for every tap, and we need to work with 2 button presses meaning 4 sets of bytes. Here, we are checking the first and third sets which both have a value of 0x7F.

The best way to work with these files is to run sudo thunar/sudo nautilus and move my files to the usr/share/mixxx/midi folder and then run sudo geany and open them up, and then open another terminal tab and run mixxx like usual. If you figure out some more functionality and controls please do send the code my way, man!

I may have some time off tonight, I will start on debugging like you said, get to know the codes and such. Thanks for your explanation above, this helps me on my way!
Also found some usefull info at Got some reading to do.
Is it possible to write custom functions in this files as well, like:

function isPressed(value)
    if (!value && value !== 0 && value !== 0x00){
        if(value == 0x7F ){
            return true;
    return false;


if (value == 0x7F) // And the jog wheel is pressed down:  


if (isPressed(value)) // And the jog wheel is pressed down:  

I havent read any documentation yet, which i know i need to do first, but this was something that popped into my mind right away when viewing your js file. I have to find out what these #x## means xD.

I believe so! We would just have to figure out a swanky adaptation of that. We can always use global variables, too, like DJCRMX2.isShiftPressed=0 or 1, and pressing shift would set the variable to 0 or 1, and we can test it in any function we choose. We wouldn’t need to make a function for every button (or one that will test any button) when we can just check the variable instead. One depends on memory, the other depends on MIDI signal.

The good news now is that I’ve figured out how to loop through all of my LEDs and test to see which ones are mapped to which. The non-obvious ones were the volume meters which were controls 73-84 meaning in hexadecimal they are 0x49 - 0x54. We’re going to have to program a function that interprets the current volume from each deck and activate the lights based off the volume and make it happen automatically.

Sounds awesome!
I’ve found out that this week, last week before vacation, has left me little to no time at all to get started on anything…
So I must postpone all of my activities for this untill I get back from vacation, sorry man :frowning:.


Thank you for your great work so far!

I am happy to have access to a RMX 2 now and would like to support you with testing and from the the Mixxx C++ codebase.

I have tested your latest mapping on Ubuntu and it works fine as you have described.

For a better change tracking I have just created a launchpad branch and added your fies: … mixxx/rmx2
You will find them here: … ntrollers/

I have also changed the names to fit to the other mappings.

I would be happy if you post your c++ code issues or ideas here or better as a Launchpad bug

Kind regards,


Thanks, D. If SysEx works I can continue development on the features and finish the 1.0.0! I’m renaming the files to the ones being included in the next mixxx update. I want to get LEDs working right and the hotcue removal buttons working. I think you guys would get the ALSA crew’s attention faster than I could, I heard one of y’all were vouching to get in touch with them. I’d appreciate that a lot!

Yo, I’m sure my SysEx code should be working. It passes an array of bytes to the function, yeah?

<control><!-- Microphone --> <status>0xF0</status> <!-- ??? --> <group>[Master]</group> <key>DJCRMX2.inboundSysex</key> <description>Utilize Microphone</description> <options> <Script-Binding/> </options> </control>

[code]/* [ Function inboundSysex ] - Version 0.1.4

  • Partially operates. If I can’t get this to work, shift is fucked.
    DJCRMX2.inboundSysex = function (data, length){
    if(data[0]==0xF0) // If a Sysex function has passed…
    { // If the function is the microphone button.
    if(data[6]==0x0D && data[10]==0x01) // If pressed
    else if(data[6]==0x0D && data[10]==0x00)

MIDI input for microphone:

It ain’t showing any more warnings, which is good news, but the microphone Talk button still doesn’t press as it’s supposed to. I’m convinced it’s just the darn data array, I’m somehow doing something totally wrong.

Just committed an update. … 2.midi.xml
It has a basic LED support and support for the Gain knobs.

I get an error message with the 0.1.3 script

Debug [Controller]: Controller in script engine is: "DJConsole Rmx2 MIDI 1" Debug [Controller]: ControllerEngine: Loading & evaluating all script code Debug [Controller]: ControllerEngine: Watching JS File: "/usr/share/mixxx/controllers/common-controller-scripts.js" Debug [Controller]: ControllerEngine: Loading "/usr/share/mixxx/controllers/common-controller-scripts.js" Debug [Controller]: ControllerEngine: Watching JS File: "/usr/share/mixxx/controllers/Hercules-DJ-Console-RMX-2-scripts.js" Debug [Controller]: ControllerEngine: Loading "/usr/share/mixxx/controllers/Hercules-DJ-Console-RMX-2-scripts.js" Warning [Controller]: ControllerEngine: No "" object in script

The jogwheels are not working anymore.
It might be an error in the script, but I can’t find any fault.

Any Idea?
I am using 1.11 r3864

I had the same problem while upgrading the RMX 2 midi mapping file to the most recent version (i.e. 3336).
In that version however the .js file has been renamed and it can not locate the .js file.
(see: … eco9puxq-2)

So I resolved the issue by renaming DJConsoleRMX2Scripts.js to Hercules-DJ-Console-RMX-2-scripts.js in /usr/share/mixxx/controllers/

hope this helps.


Just wanted to say thanks for all your hard work. I recently picked up a RMX2 from a guy for $50 and I’m happy to say the script and mapping worked great. (Mixxx 1.10, Linux Mint XFCE 13, Kernel 3.2) I haven’t tried to get the audio hardware working, but my laptop has 2 soundcards so I’m cool just to mess around like this.

Good news, thank you.

MIxxx 1.10 is rather old. You should update to latest release version 1.11 via ppa

Open a terminal, and enter:
sudo add-apt-repository ppa:mixxx/mixxx
sudo apt-get update
sudo apt-get install mixxx libportaudio2

If you are brave enough you might test the latest 1.12 alpha

It is still in untested alpha stadium, but it enables 14 bit precision of RMX2 sliders and offers a nice mapping Wizard.
All test results and wishes are welcome at

For the Audio part you need to install the kernel patch from

Hi all, I was wondering if this RMX 2 mapping was friendly to new Mixxx users?
I got burned by a VMS4.1, the RMX2 looks like a good board but I don’t want to wind up stumped :}
I’m on Mixxx 1.11, Ubuntu 13.

Hi jefm,

what is your question?
The only controller I have uses is the RMX 2 … and it works fine with Mixxx 1.11 and Ubuntu 13.4

Hello daschuer,
I think you just answered my question, heh. The RMX 2 looked well supported from this thread and others but was not on the hardware list yet, just wanted to make sure things were good. Sounds like they are.

hej there!
for two hours I’m playing with my brandnew RMX2 on mixxx. Woohoo!
I was glad to find the mapping and script at ~mixxxcontributors/mixxx/rmx2, since the RMX2 is not listed as supported in the wiki.

However, I noticed all Faders and two knobs (Head mix & Master Vol.) are ridiculously jumping around when slided. Mixxx shows some audible & visible glitches when this happens.
So, I had a look at the .xml and started Mixxx with --controllerDebug. When sliding one of the faders, I received two values: 1) constantly rising from 00 to 7F 2) rolling over&over&over. Seems like the values of were not picked up correctly.
–Edit: I got all of them working by deleting the …… parts in the .xml, but I it’s just so I can start playing with the device… The resolution of the affected faders and knobs is not too precise now.
And the jog wheels are not working. At all.

I’willing to dive into this issues, but I have no idea where to start. Maybee someone could point me in the right direction… Thanks!

Ubuntu Studio 14.04
Mixxx 1.11
Hercules DJ Console RMX 2


Is your first post in this thread up-to-date?
I want to buy this console but I want first to know if I can use all of it functionalities.

The first post is out of date.
This reflects the current state better: … sole_rmx_2

If I can suggest: it would be really helpful to symbolically show the level of support (as of latest release) of devices in wiki.
Because when I read wiki pages I ask myself if that is really Mixxx controller support state or how it should be, like in the manual?
Then my experience has been that digging in the official forum thread resulted in misleading infos.
So I bought another device (which was my second choice).

I can’t think of any practical way to rate the level of support in a consistent way. Part of the point of having documentation on the wiki is to let users judge that for themselves before they buy a controller. Also part of the point is that there is often a lot of outdated and extraneous info on the forum thread, so the wiki page for each controller is a place to consolidate the most complete information. If the documentation on a wiki page is unclear or incomplete, that’s an issue that would be helpful to bring up.