Push-and-Hold in custom midi mapping

I’m trying to make a custom mapping for a Akai MPK Midi. I’ve gotten pretty far using just the midi-learner (Akai MPK Mini.midi.xml (9.9 KB)) but it has a couple of bugs:

  1. The cue button doesn’t work right
  2. The pitchbend buttons don’t work

I believe the issue in both cases is that the midi learner only lets me react to Note On or Note Off events; this is fine for most controls, however for cue and pitchbend I want push-and-hold behaviour; that is: I want them to trigger on Note On and stay active until I send Note Off. But I only see On, Off, CC and Pitch Bend:

Is it possible to do push-and-hold just through the Mixxx UI or do I need to write a javascript file?

These threads sounded like they should help me but they didn’t:

Thanks for any tips you can send my way! Cheers!

Also do I have the terminology wrong? Mapping for the VCI-300 - #44 by tapir defines

press it longer (push-and-hold) to enable sync permanently

If push-and-hold isn’t the right terminology for what I’m looking for, what is the right terminology? Thanks.

Hi!

I think you’re trying to say, you want to trigger a function when you long-press the cue button, rather than a short-press.

It’s relatively easy if you can code in javascript. You need to use script timers.

Check out the latter half of this page:
Script timers

I added the same functionality you’re looking for in my Pioneer DDJ-SX3 controller map script. You can see the source here:

Pioneer DDJ-SX3 Controller Map Script

Do a search for the function: PioneerDDJSX3.syncButton
That’s where the code starts.

I hope that helps.

Thanks for the example. It helps a lot to get a jumpstart with some real working code.

I’ve read it but I don’t think that’s what I’m looking for. I’m not looking to have two functions. one triggered by tapping and one by holding. Instead I just want one single function, and I feel like I must be missing something because this seems pretty basic.

The learner generated this code for the first cue button:

<control>
<group>[Channel1]</group>
<key>cue_default</key>
<description>MIDI Learned from 2 messages.</description>
<status>0x90</status>
<midino>0x35</midino>
<options>
<normal/>
</options>
</control>

I believe(?) this is doing something like this Javascript:

AkaiMPK.cueButton = function(channel, control, value, status, group) {
    engine.setValue(group, "cue_default", value);
};

But this is wrong some how. Apparently I don’t want it to just do that.

I figured out what I was missing though: according to mixxxcontrols, the cue button is:

In CDJ mode, when playing, returns to the cue point and pauses. If stopped, sets a cue point at the current location. If stopped and at a cue point, plays from that point until released (set to 0.)

Range: binary

that, plus using

mixxx --controllerDebug

in combination with

<control>
<group>[Channel1]</group>
<key>script.midiDebug</key>
<description>MIDI Learned from 2 messages.</description>
<status>0x90</status>
<midino>0x35</midino>
<options>
<script-binding/>
</options>
</control>

clued me in to the problem: I wasn’t listening for Note Offs, which meant that the cue button would trigger and then hold forever.

Sp this is the simple fix I was looking for: just listen for both Note On and Note Off at the same time:

            <control> 
                <group>[Channel1]</group>
                <key>cue_default</key>
                <description>MIDI Learned from 2 messages.</description>
                <status>0x90</status> <!-- note on -->
                <midino>0x35</midino>
                <options> 
                    <normal/>
                </options>
            </control>

            <control> 
                <group>[Channel1]</group>
                <key>cue_default</key>
                <description>MIDI Learned from 2 messages.</description>
                <status>0x80</status>  <!-- note off -->
                <midino>0x35</midino>
                <options> 
                    <normal/>
                </options>
            </control>


            <control> 
                <group>[Channel2]</group>
                <key>cue_default</key>
                <description>MIDI Learned from 2 messages.</description>
                <status>0x90</status>  <!-- note on -->
                <midino>0x41</midino>
                <options> 
                    <normal/>
                </options>
            </control>

            <control> 
                <group>[Channel2]</group>
                <key>cue_default</key>
                <description>MIDI Learned from 2 messages.</description>
                <status>0x80</status>  <!-- note off -->
                <midino>0x41</midino>
                <options> 
                    <normal/>
                </options>
            </control>

which shows up in the UI like this:

Now the keys on my midi keyboard behave the same as clicking on the cue button with the mouse, or pressing and holding the f or ; keys on my typing keyboard.

Next I will try to see if the rate_temp_up and rate_temp_down controls have the same simple solution.

Yes, it was the same fix for the pitchbend. In fact the Deere skin makes it obvious that the pitch bend is getting jammed once I release the pitch bend midi key:

2021-09-09-021917_77x193_scrot

In Maintening a key pressed doesn't have any effect? - #2 by ronso @ronso explained

there are controls supposed to be ‘triggered’ once (like beatjump_backwards) or those that can be pressed amd hold (rewind for example).

and so I guess my conclusion is that for the former kind, the midi learner is enough, but for the latter you must catch both Note On and Note Off and for that you need to manually edit the XML or manually add a row to the Input Mappings table.

For future reference, here’s my work-in-progress mapping that applies this lesson: Akai MPK Mini.midi.xml (13.0 KB)