MIDI-OX User Forum (http://www.midiox.com/cgi-bin/yabb/YaBB.pl)
MIDI-OX >> Scripting Questions >> Korg padKONTROL in Native mode
(Message started by: raintalk on Oct 12th, 2008, 4:59pm)

Title: Korg padKONTROL in Native mode
Post by raintalk on Oct 12th, 2008, 4:59pm
The Korg padKONTROL has a "Native" mode, where every button pushed and knob turned will send a mini 9 byte sysex of data.

This is handy when you want to use everything including the buttons that don't normally send MIDI data.   The problem is I can't see a way in MIDI-OX to translate mini sysex into normal MIDI messages?  But thankfully it has a scripting interface that can do this.   I wrote a script example.  I thought I would post it here in case there are others looking into this.  

I basically translate the sysex to normal midi where I can remap it as I want.  I know about commercial tools for the padKontrol that do this, but they all seem to have limitations or just one host application in mind,  with Midi-OX I can do anything for any application.

Korg padKontrol Sysex info can be found here under "useful sysex strings":
http://kpkproject.twoday.net/
And
http://static.twoday.net/kpkproject/files/Padkontrol-Sysex-Imp.pdf

The perl is perlscript 5.10 from ActiveState.
The only reason I use perlscript is my familiarity with it.  There's no other good reason to use it over python, vb, or javascript, that I know of.  

I have to split the script into several posts due to its size.
Set the midi-in and out as indicated in the script.
Write this script out as padKontrol.pls, then just run it.
Just an example, works for me, YMMV, hope this helps someone.

Title: Re: Korg padKONTROL in Native mode (part 2)
Post by raintalk on Oct 12th, 2008, 5:01pm
---------------------------------------

# perlscript
# Not shown below, Set:
# Midi-In "padKONTROL 1 Port A"
# Midi-out "padKONTROL CTRL 1" and any other port you want
#
use feature qw(switch);

my $mox = $WScript->CreateObject("Midiox.MoxScript.1", "Sink_");

die "can't start Mox" if ! defined $mox;
#use strict;

use constant SP => " "; #A Space
use constant SYSEX_START => 'f0';
use constant SYSEX_END => SP.'f7'; # With a Space

# Always the same for padKontrol
use constant PK_HEADER => SYSEX_START.SP.'42 40 6e 08 ';

# Some common Sysex's for padKontrol
use constant PkStartNativeMode => 'F0 42 40 6E 08 00 00 01 F7';
use constant PkStartSysex=>'F0 42 40 6E 08 3F 2A 00 00 05 05 05 7F 7E 7F 7F 03 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 F7';
use constant PkAllLightsOn => 'F0 42 40 6e 08 3f 0a 01 7f 7f 7f 7f 7f 03 38 38 38 F7';
use constant PkAllLightsOff => PK_HEADER.'f0 42 40 6e 08 3f 0a 01 00 00 00 00 00 00 00 00 00 '.SP.SYSEX_END;

use constant {
     PkRotary => 0x43,
     PkPad => 0x45,
     PkKnob => 0x49,
     PkButton => 0x48,
     PkPedal => 0x47,
     PkXY => 0x4B,
     PkXYButton => 32,
     LIGHT_CMD => PK_HEADER.SP.'01'.SP,
     LED_CMD => PK_HEADER.SP.'22 04 00',
     LIGHT_ON => ' 20',
     LIGHT_BLINK => ' 63',
     LIGHT_OFF => ' 00',
     LIGHT_FLASH => ' 44',
     LightPkDec01 => 0x6f,
     LightPkDec02 => 0x77,
     LightPkDec03 => 0x7f,
     LightPkKnob1Assign=>0x1d,
     LightPkKnob2Assign=>0x1e,
     LIGHT_TOGGLE=>0xff, # Not a real value used to toggle the light
};

# Midi Constants
use constant {
   CHANNEL_PRESSURE => 0xD0,
   CONTROL_CHANGE => 0xB0,
   NOTE_OFF => 0x80,
   NOTE_ON => 0x90,
   PITCH_BEND => 0xE0,
   POLY_PRESSURE => 0xA0,
   PROGRAM_CHANGE => 0xC0,
   # You get the idea ...
};


# Hash to hold status of lights
my $lights = {};

$mox->SendSysexString(PkStartNativeMode);
$mox->SendSysexString(PkStartSysex);
$mox->SendSysexString(PkAllLightsOn);
sleep 1;
$mox->SendSysexString(PkAllLightsOff);

# Turn the top 8 Pad lights on.
light(LIGHT_ON,0);
light(LIGHT_ON,1);
light(LIGHT_ON,2);
light(LIGHT_ON,3);
light(LIGHT_ON,4);
light(LIGHT_ON,5);
light(LIGHT_ON,6);
light(LIGHT_ON,7);

# setting up a min and max for the LED display as you turn the rotary encoder
my $minLED = 0;
my $maxLED = 99;
my $currentLED = $minLED;
setLED(sprintf("%03d",$currentLED));

$mox->{FireMidiInput} = 1;
$mox->{DivertMidiInput} = 1;
$WScript->Echo('Click "OK" to end MidiOx');
$mox->{DivertMidiInput} = 0;

Title: Re: Korg padKONTROL in Native mode (part 3)
Post by raintalk on Oct 12th, 2008, 5:02pm
sub Sink_SysExInput {
     my $data = $_[0]; #Everything comes in as a single string.
     my $data = [map {hex($_)} split(/ /,$data)]; #Split it into an array.
     my $type = $data->[5] ; # Header is 0 .. 4, 5 is the command type.
     given($type) {
           when(PkPad) {
                 my $pad;
                 my $vel = $data->[7];
                 if ( $data->[6] < 64 ) {
                       #Note off - the pad == the pad number
                       $pad = $data->[6];
                       light(LIGHT_TOGGLE,$pad);
                       $mox->OutputMidiMsg(-1,NOTE_OFF,$pad,$vel);
                 }
                 else {
                       #Note on - the pad == the pad number - 64 (?)
                       $pad = $data->[6] - 64;
                       light(LIGHT_TOGGLE,$pad);
                       $mox->OutputMidiMsg(-1,NOTE_ON,$pad,$vel);
                 }
           }
           when([PkButton, pkpedal]) {
                 my $which = $data->[6];
                 my $vel = $data->[7];
                 # When a button is pushed a velocity > 64 is note on.
                 my $noteOn = $vel > 64 ? 1 : 0;

                 if ($which != PkXYButton ) {
                       # Ignore if it's the XY pad.
                       # The switch number is the number + 16
                       $which += 16;
                       if ($noteOn) {
                             light(LIGHT_TOGGLE,$which);
                             $mox->OutputMidiMsg(-1,NOTE_ON,$which,$vel);
                       }
                       else {
                             light(LIGHT_TOGGLE,$which);
                             $mox->OutputMidiMsg(-1,NOTE_OFF,$which,$vel);
                       }
                 }
                 else {
                       light(LIGHT_FLASH,LightPkDec02);
                 }
           }
           when(PkXY) {
                 my ($x,$y) = ($data->[7],$data->[8]);
                 # Do something with this
           }
           when(PkRotary) {
                 my ($x,$y) = ($data->[7],$data->[8]);
                 if ( $data->[7] == 1 ) {
                       $currentLED++ if $currentLED < $maxLED;
                       light(LIGHT_FLASH,LightPkDec01);
                 }
                 else {
                       $currentLED-- if $currentLED > $minLED;
                       light(LIGHT_FLASH,LightPkDec03);
                 }
                 setLED(sprintf("%03d",$currentLED));
           }
           when(PkKnob) {
                 my $knob = $data->[6];
                 my $outknob = $knob == 1 ? 10 : 20;
                 my $value = $data->[7];
                 $mox->OutputMidiMsg(-1,CONTROL_CHANGE,$outknob,$value);
                 light(LIGHT_FLASH,LightPkKnob1Assign + $knob);

           }
           default {}
     }
}

# Sub to turn on, off, blink, and flash lights.  
# The external hash $lights stores the current light states.
# Toggle with toggle on off lights on, or an on light off
sub light {
     my $cmd = $_[0];
     my $light = sprintf("%02x",$_[1]);
     if ($cmd == LIGHT_TOGGLE) {
           if ($lights->{$light} == LIGHT_ON ) {
                 $lights->{$light} = LIGHT_OFF;
                 $cmd = LIGHT_OFF;
           }
           elsif ($lights->{$light} == LIGHT_OFF ) {
                 $lights->{$light} = LIGHT_ON;
                 $cmd = LIGHT_ON;
           }
           else {
                 $cmd = LIGHT_FLASH;
           }
     }
     elsif ($cmd != LIGHT_FLASH ) {
           $lights->{$light} = $cmd;
     }
     $mox->SendSysexString(LIGHT_CMD.$light.SP.$cmd.SYSEX_END);
};

# Sub to set the characters in the 3 segment LED display.
# Not all characters are readible.  You can also set individual segments with the light command above.
sub setLED {
     my @c = @_;
     if (scalar @c < 2 ) {
           @c = split //,$c[0];
     }
     $lights{LED} = sprintf "%02x %02x %02x", ord $c[0], ord $c[1], ord $c[2];
     $mox->SendSysexString(LED_CMD.$lights{LED}.SYSEX_END);
};




Title: Re: Korg padKONTROL in Native mode
Post by jodeci on Jan 16th, 2009, 9:47am
Hi Raintalk

Thanks for this....it's just what I have been looking for.  I have purchased NativeKontrol but that is geared towards specific apps.

As I'm new to scripting could you just run through the steps of the parameters I need to change to get this working.

Thanks

J



MIDI-OX User Forum » Powered by YaBB 1 Gold - SP 1.3.1!
YaBB © 2000-2003. All Rights Reserved.