I have updated the midi configuration for Hercules RMX to work better
with Mixxx 1.8.0. A patch is attached. See changes below.

I have a few questions also:
1. Has timers been implemented yet?
2. The list of controls for midi mapping on the wiki seem to be
incomplete. Is the there a complete list?
3. Jog wheel seeking is considerably slower in 1.8.0beta1 than 1.7.1.
Has something changed? On my RMX set to "normal" 1s equals to ~15
revolutions.
4. Scratch doesn't seem to work well on a stopped track. Track moves
much faster backwards that forward. Why?
5. Can scratch decay be handled by the engine instead of scripts?
Don't all controls need a common handling of that?

Changes:
*Forward and backward buttons used for seeking (fwd/back) instead of
skipping to next/previous track.
*Beat sync is handled through a script to turn on button LEds.
*Pitch Reset implemented through script.
*Reset of Sync and Reset LEDs through script bound to rate.
*Previous and next split into separate script functions to enable remapping.
*Left and Right connected to playlist naviation
Select[Next/Prev]Playlist. (Seem to be track selection though)
*Looping connected, buttons 2, 5 and 6 mapped to loop_in, loop_out and
reloop_exit
*Speedup of jog wheel seeking in a stopped track.
*Removed getGroup in favour of group parameter.
*Fixed jog wheel scroll in library.
*Fixed cue play behaviour. Now playing as long as Cue is held down.

//Anders
=== modified file 'mixxx/res/midi/Hercules DJ Console RMX.midi.xml'
--- mixxx/res/midi/Hercules DJ Console RMX.midi.xml	2009-05-25 23:04:13 +0000
+++ mixxx/res/midi/Hercules DJ Console RMX.midi.xml	2010-02-28 23:46:08 +0000
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
-<MixxxMIDIPreset vschemaVersion="1" mixxxVersion="1.7.0">
+<MixxxMIDIPreset vschemaVersion="1" mixxxVersion="1.8.0">
     <info>
         <name>Hercules DJ Console RMX</name>
         <author>Garth Dahlstrom</author>
+        <author>Anders Gunnarsson</author>
         <description>This is a complete mapping for a Hercules DJ Console RMX. Requires scripting.</description>
     </info>
     <controller id="Hercules DJ Console RMX MIDI">
@@ -161,7 +162,7 @@
             </control>
             <control>
                 <group>[Channel1]</group>
-                <key>PrevTrack</key>
+                <key>back</key>
                 <status>0xB0</status>
                 <midino>0x09</midino>
                 <options>
@@ -170,7 +171,7 @@
             </control>
             <control>
                 <group>[Channel1]</group>
-                <key>NextTrack</key>
+                <key>fwd</key>
                 <status>0xB0</status>
                 <midino>0x0A</midino>
                 <options>
@@ -191,7 +192,6 @@
                 <midino>0x31</midino>
                 <options/>
             </control>
-
             <control>
                 <group>[Master]</group>
                 <key>volume</key>
@@ -258,7 +258,7 @@
             </control>
             <control>
                 <group>[Channel2]</group>
-                <key>PrevTrack</key>
+                <key>back</key>
                 <status>0xB0</status>
                 <midino>0x21</midino>
                 <options>
@@ -267,7 +267,7 @@
             </control>
             <control>
                 <group>[Channel2]</group>
-                <key>NextTrack</key>
+                <key>fwd</key>
                 <status>0xB0</status>
                 <midino>0x22</midino>
                 <options>
@@ -363,20 +363,38 @@
 <!-- Sync Buttons -->
             <control>
                 <group>[Channel1]</group>
-                <key>beatsync</key>
+                <key>HerculesRMX.beatSync</key>
                 <status>0xB0</status>
                 <midino>0x07</midino>
                 <options>
-                    <Button/>
+                    <Script-Binding/>
                 </options>
             </control>
             <control>
                 <group>[Channel2]</group>
-                <key>beatsync</key>
+                <key>HerculesRMX.beatSync</key>
                 <status>0xB0</status>
                 <midino>0x1F</midino>
                 <options>
-                    <Button/>
+                    <Script-Binding/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel1]</group>
+                <key>HerculesRMX.rateReset</key>
+                <status>0xB0</status>
+                <midino>0x11</midino>
+                <options>
+                    <Script-Binding/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel2]</group>
+                <key>HerculesRMX.rateReset</key>
+                <status>0xB0</status>
+                <midino>0x20</midino>
+                <options>
+                    <Script-Binding/>
                 </options>
             </control>
             <control>
@@ -389,7 +407,7 @@
                 </options>
             </control>
             <control>
-                <key>HerculesRMX.up_down_arrows</key>
+                <key>HerculesRMX.prev</key>
                 <group>[Playlist]</group>
                 <status>0xB0</status>
                 <midino>0x2A</midino>
@@ -398,7 +416,7 @@
                 </options>
             </control>
             <control>
-                <key>HerculesRMX.up_down_arrows</key>
+                <key>HerculesRMX.next</key>
                 <group>[Playlist]</group>
                 <status>0xB0</status>
                 <midino>0x2B</midino>
@@ -407,6 +425,24 @@
                 </options>
             </control>
             <control>
+                <key>SelectPrevPlaylist</key>
+                <group>[Playlist]</group>
+                <status>0xB0</status>
+                <midino>0x2C</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
+            <control>
+                <key>SelectNextPlaylist</key>
+                <group>[Playlist]</group>
+                <status>0xB0</status>
+                <midino>0x2D</midino>
+                <options>
+                   <Button/>
+                </options>
+            </control>
+            <control>
                 <group>[Channel1]</group>
                 <key>reverse</key>
                 <status>0xB0</status>
@@ -424,137 +460,60 @@
                     <Switch/>
                 </options>
             </control>
-
-<!--
-            <control>
-                <group>[Master]</group>
-                <key>headMix</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>transform</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>start</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>end</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>cue_gotoandstop</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>wheel_touch_switch</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>rate_temp_up</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>rate_temp_down</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel1]</group>
-                <key>loop</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>transform</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>start</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>end</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>cue_gotoandstop</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>wheel_touch_sensor</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>wheel_touch_switch</key>
-                <status>0xB0</status>
-                <midino>40x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>rate_temp_up</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>rate_temp_down</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options>
-                    <Invert/>
-                </options>
-            </control>
-            <control>
-                <group>[Channel2]</group>
-                <key>loop</key>
-                <status>0xB0</status>
-                <midino>0x2E</midino>
-                <options/>
-            </control>
--->
+            <control>
+                <group>[Channel1]</group>
+                <key>loop_in</key>
+                <status>0xB0</status>
+                <midino>0x02</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel2]</group>
+                <key>loop_in</key>
+                <status>0xB0</status>
+                <midino>0x1A</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel1]</group>
+                <key>loop_out</key>
+                <status>0xB0</status>
+                <midino>0x05</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel2]</group>
+                <key>loop_out</key>
+                <status>0xB0</status>
+                <midino>0x1D</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel1]</group>
+                <key>reloop_exit</key>
+                <status>0xB0</status>
+                <midino>0x06</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
+            <control>
+                <group>[Channel2]</group>
+                <key>reloop_exit</key>
+                <status>0xB0</status>
+                <midino>0x1E</midino>
+                <options>
+                    <Button/>
+                </options>
+            </control>
         </controls>
 
     <outputs>

=== modified file 'mixxx/res/midi/Hercules-DJ-Console-RMX-scripts.js'
--- mixxx/res/midi/Hercules-DJ-Console-RMX-scripts.js	2009-12-27 01:46:49 +0000
+++ mixxx/res/midi/Hercules-DJ-Console-RMX-scripts.js	2010-02-28 23:58:37 +0000
@@ -4,7 +4,11 @@
 // "[Channel1] cue blink":0x3C,
 // "[Channel2] cue blink":0x54,
 "[Channel1] cue":0x0C,
-"[Channel2] cue":0x24
+"[Channel2] cue":0x24,
+"[Channel1] beatsync":0x07,
+"[Channel2] beatsync":0x1F,
+"[Channel1] pitchreset":0x11,
+"[Channel2] pitchreset":0x20
 // "[Channel1] play":0x0B,
 // "[Channel2] play":0x23
  };
@@ -14,10 +18,13 @@
 HerculesRMX.scratchMode = false;
 HerculesRMX.playlistJogScrollMode = false;
 HerculesRMX.decayLast = new Date().getTime();
-HerculesRMX.decayInterval = 50;
+HerculesRMX.decayInterval = 20;
 HerculesRMX.decayRate = 300;
 HerculesRMX.cueButton = { "[Channel1]": false, "[Channel2]": false};
 HerculesRMX.cuePlay = { "[Channel1]": false, "[Channel2]": false};
+//HerculesRMX.scratchTimer = 0;
+HerculesRMX.scratching = false;
+HerculesRMX.syncing = false;
 // TODO HerculesRMX controls should be divided into groups...  then signals should directed 
 // to each group without thinking about specific controls to allow for easy rebinding.
 
@@ -32,69 +39,60 @@
 
     engine.connectControl("[Channel1]","playposition","HerculesRMX.wheelDecay");
     engine.connectControl("[Channel2]","playposition","HerculesRMX.wheelDecay");
+    engine.connectControl("[Channel1]","rate","HerculesRMX.rateChange");
+    engine.connectControl("[Channel2]","rate","HerculesRMX.rateChange");
 }
 
 HerculesRMX.wheelDecay = function (value) {    
-//    if (engine.getValue("[Channel1]","play") + engine.getValue("[Channel2]","play") == 0) { return; }
-    engine.getValue("[Channel1]","play")
-
-    var currentDate = new Date().getTime();
-    // print(currentDate);
-    if (currentDate > HerculesRMX.decayLast + HerculesRMX.decayInterval) {
-       HerculesRMX.decayLast = currentDate;
-
-       if (HerculesRMX.debug) print(" new playposition: " + value + " decayLast: "+ HerculesRMX.decayLast);
-       if (HerculesRMX.scratchMode) { // do some scratching
+   if (HerculesRMX.scratching) {
+      var currentDate = new Date().getTime();
+      if (HerculesRMX.debug) print(currentDate);
+      if (currentDate > HerculesRMX.decayLast + HerculesRMX.decayInterval) {
+         HerculesRMX.decayLast = currentDate;
+         if (HerculesRMX.debug) print(" new playposition: " + value + " decayLast: "+ HerculesRMX.decayLast);
          if (HerculesRMX.debug) print("Scratch deck1: " + engine.getValue("[Channel1]","scratch") + " deck2: "+ engine.getValue("[Channel2]","scratch"));
-         // print("do scratching " + jogValue);
-         // engine.setValue(group,"scratch", jogValue); // /64);
-
-  	 var jog1DecayRate = HerculesRMX.decayRate * (engine.getValue("[Channel1]","play") ? 1 : 5);
+         var jog1DecayRate = HerculesRMX.decayRate * (engine.getValue("[Channel1]","play") ? 1 : 3);
          var jog1 = engine.getValue("[Channel1]","scratch"); 
-	 if (jog1 != 0) {
-         if (Math.abs(jog1) > jog1DecayRate) {  
+         if (jog1 != 0) {
+            if (Math.abs(jog1) > jog1DecayRate) {  
                engine.setValue("[Channel1]","scratch", (jog1 / jog1DecayRate).toFixed(2));
             } else {
                engine.setValue("[Channel1]","scratch", 0);
             }
          }
-	 var jog2DecayRate = HerculesRMX.decayRate * (engine.getValue("[Channel2]","play") ? 1 : 5);
+         var jog2DecayRate = HerculesRMX.decayRate * (engine.getValue("[Channel2]","play") ? 1 : 3);
          var jog2 = engine.getValue("[Channel2]","scratch"); 
-	  if (jog2 != 0) {
-	     if (Math.abs(jog2) > jog2DecayRate) {  
-                engine.setValue("[Channel2]","scratch", (jog2 / jog2DecayRate).toFixed(2));
-             } else {
-                engine.setValue("[Channel2]","scratch", 0);
-             }
-          }
+         if (jog2 != 0) {
+         if (Math.abs(jog2) > jog2DecayRate) {  
+            engine.setValue("[Channel2]","scratch", (jog2 / jog2DecayRate).toFixed(2));
+         } else {
+            engine.setValue("[Channel2]","scratch", 0);
+         }
+      }
+      if (engine.getValue("[Channel1]","scratch") == 0 && engine.getValue("[Channel1]","scratch") == 0) {
+         HerculesRMX.scratching = false;
+         //   engine.stopTimer(HerculesRMX.scratchTimer);
+         //   HerculesRMX.scratchTimer = 0;
+         }
       } 
-    }
+   }
+}
+
+//Rate change event handler to reset sync and reset leds
+HerculesRMX.rateChange = function (value, group) {
+   if (!HerculesRMX.syncing) {
+      midi.sendShortMsg(0xB0, HerculesRMX.leds["[Channel1] beatsync"], HerculesRMX.ledOff);
+      midi.sendShortMsg(0xB0, HerculesRMX.leds["[Channel2] beatsync"], HerculesRMX.ledOff);
+   }
+   if (value != 0) {
+      midi.sendShortMsg(0xB0, HerculesRMX.leds[group + " pitchreset"], HerculesRMX.ledOff);
+   }
+   HerculesRMX.syncing = false;
 }
 
 HerculesRMX.shutdown = function(id) {
 }
 
-HerculesRMX.getGroup = function (control){ 
-// get the "group" that used to be provided in group, this is not reusable across devices
-// and also breaks remapping of these functions to other buttons.  
-   var controlToGroup = { 
-                0x2F:"[Channel1]", 
-                0x30:"[Channel2]", 
-		0x0C:"[Channel1]", // Cue
-     		0x24:"[Channel2]",
-		0x0B:"[Channel1]", // Play
-		0x23:"[Channel2]",
-		0x0D:"[Channel1]", // Stop
-		0x25:"[Channel2]",
-		0x12:"[Channel1]", // Load Deck
-		0x16:"[Channel2]",
-		0x2F:"[Channel1]", // Jog Wheels 
-		0x30:"[Channel2]" 
-   }
-   return controlToGroup[control];
-}
-
-
 HerculesRMX.toggle_scratch_mode = function (channel, control, value, status) {
     if (value > 0) {
 	HerculesRMX.scratchMode = !HerculesRMX.scratchMode;
@@ -102,8 +100,7 @@
     }
 }
 
-HerculesRMX.stop_and_reset_track = function (channel, control, value, status) {
-   var group = HerculesRMX.getGroup(control);
+HerculesRMX.stop_and_reset_track = function (channel, control, value, status, group) {
    if (engine.getValue(group, "duration") == 0) { if (value) print("No song on " + group); return; };
    if (value > 0) {
         engine.setValue(group,"cue_default",0);
@@ -116,41 +113,50 @@
    }
 }
 
-HerculesRMX.up_down_arrows = function (channel, control, value, status) {
-   // TODO replace with two seperate functions (Next/Prev) to make them distinctly rebindable.
-   HerculesRMX.playlistJogScrollMode = value > 0;
-   if (value > 0) {
-     switch (control) {
-        case 0x2A: engine.setValue("[Playlist]","SelectPrevTrack", (value > 0)); break;
-        case 0x2B: engine.setValue("[Playlist]","SelectNextTrack", (value > 0)); break;
-     }
+HerculesRMX.next = function (channel, control, value, status) {
+   HerculesRMX.playlistJogScrollMode = value > 0;
+   if (value > 0) {
+      engine.setValue("[Playlist]","SelectNextTrack", (value > 0));
+   }
+}
+
+HerculesRMX.prev = function (channel, control, value, status) {
+   HerculesRMX.playlistJogScrollMode = value > 0;
+   if (value > 0) {
+      engine.setValue("[Playlist]","SelectPrevTrack", (value > 0));
    }
 }
                  
-HerculesRMX.jog_wheel = function (channel, control, value, status) {
+HerculesRMX.jog_wheel = function (channel, control, value, status, group) {
 //  7F > 40: CCW Slow > Fast - 127 > 64 
 //  01 > 3F: CW Slow > Fast - 0 > 63
-   var group = HerculesRMX.getGroup(control);
 //   print ("Wheel");
 //   script.debug(group, control, value, status);
 
    var jogValue = value >=0x40 ? value - 0x80 : value; // -64 to +63, - = CCW, + = CW
    if (HerculesRMX.playlistJogScrollMode) { // zip through library quickly
-        engine.setValue("[Playlist]","SelectTrackKnob", jogValue);
+	if (jogValue > 0) {
+           engine.setValue("[Playlist]","SelectNextTrack", 1);
+	} else if (jogValue < 0) {
+           engine.setValue("[Playlist]","SelectPrevTrack", 1);
+        }
    } else if (HerculesRMX.scratchMode) { // do some scratching
        if (HerculesRMX.debug) print("do scratching value:" + value + " jogValue: " + jogValue );
-       // engine.setValue(group,"scratch", engine.getValue(group,"scratch") + (jogValue/64));
-       engine.setValue(group,"scratch", (engine.getValue(group,"scratch") + (jogValue/64)).toFixed(2));
+       engine.setValue(group,"scratch", jogValue);
+       //if (!HerculesRMX.scratchTimer) {
+       if (!HerculesRMX.scratching) {       
+          //HerculesRMX.scratchTimer = engine.beginTimer(HerculesRMX.decayInterval, "HerculesRMX.wheelDecay", false);
+	  HerculesRMX.scratching = true;
+          //print("Started timer with id: " + HerculesRMX.scratchTimer);
+       }
    } else { // do pitch adjustment
-       var newValue = jogValue; //(engine.getValue(group,"wheel") + (jogValue/5)).toFixed(2);
-//       if (newValue > 127) { newValue = 127; }
+       var newValue = jogValue * (engine.getValue(group,"play") ? 1 : 10);
        if (HerculesRMX.debug) print("do pitching adjust " + jogValue + " new Value: " + newValue);
        engine.setValue(group,"jog", newValue);
    }
 }
 
-HerculesRMX.cue = function (channel, control, value, status) {
-   var group = HerculesRMX.getGroup(control);
+HerculesRMX.cue = function (channel, control, value, status, group) {
    if (engine.getValue(group, "duration") == 0) { if (value) print("No song on " + group); return; };
 
    if (value) { // Down
@@ -161,9 +167,8 @@
    } else { // Release
      if (HerculesRMX.debug) print("R. Play: " + engine.getValue(group,"play") + " PlayPosition: " + engine.getValue(group,"playposition") + " cue_default: "+ engine.getValue(group,"cue_default"));
 
-     if (HerculesRMX.cuePlay[group]) {
-//       engine.setValue(group,"cue_default",0);
-        engine.setValue(group,"play",1);
+     if (HerculesRMX.cueButton[group]) {
+        engine.setValue(group,"cue_default",0);
      }
      midi.sendShortMsg(0xB0, HerculesRMX.leds[group + " cue"], HerculesRMX.ledOff);
      HerculesRMX.cuePlay[group] = false;
@@ -171,9 +176,25 @@
    }
 }
 
-HerculesRMX.play = function (channel, control, value, status) {
+
+
+HerculesRMX.beatSync = function (channel, control, value, status, group) {
+   if (value) {
+      HerculesRMX.syncing = true;
+      engine.setValue(group,"beatsync",0);
+      midi.sendShortMsg(0xB0, control, HerculesRMX.ledOn);
+   }
+}
+
+HerculesRMX.rateReset = function (channel, control, value, status, group) {
+   if (value) {
+      engine.setValue(group,"rate",0);
+      midi.sendShortMsg(0xB0, control, HerculesRMX.ledOn);
+   }
+}
+
+HerculesRMX.play = function (channel, control, value, status, group) {
    // Only send events when play is pushed, not when it comes back up.
-   var group = HerculesRMX.getGroup(control);
    if (engine.getValue(group, "duration") == 0) { if (value) print("No song on " + group); return; };
 
    if (value) {

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to