Dynamic composition of a SysEx message with variable content and length

Thanks! That’s quite the hack but it works great! I just wrote code to show the current rackspace name on my Arturia Keylab mk2’s LCD screen. A couple notes/wishlist items, and I’ll share the code at the bottom:

  • Global Scripts would be nice. If the interacted with the rig system that would be even better (though you’d probably need to add oop and inheritance to GPScript for the last bit so I understand that’s a stretch :D)
  • Some sort of way to share code between rackspaces, even if it’s just a basic #include style copypaste
  • Understand that documentation is a pain, especially for something like this. Maybe make it a wiki or host it on github so that the community can help?
  • Add me to the list of people asking for OnSongActivate - Looks like from another thread you’ve written the code so hopefully it’s easy!
  • String constant expressions are pass by reference, which leads to the rather confusing behavior that var s : String; s = "foo"; bar(s); is not equivalent to bar("foo"); if bar modifies its argument. If all non-primitive types exhibit this behavior it would be helpful if it was explained in the tutorial.

I’ll share my code in case anyone else is using the keylab:

var
    Keylab2          : MidiOutBlock;
    SysEx            : SysexManager;
    KEYLAB2_LCD_PRE  : String;
    KEYLAB2_LCD_SEP  : String;
    KEYLAB2_LCD_END  : String;
    ASCII_STRING     : String;
    ASCII_HEX_STRING : String array;

Initialization
    ASCII_STRING = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[Y]^_`abcdefghijklmnopqrstuvwxyz{|}><";
    ASCII_HEX_STRING = ["20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F","30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F","40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F","50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F","60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F","70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F"];
    KEYLAB2_LCD_PRE = "# F0 00 20 6B 7F 42 04 00 60 01 ";
    KEYLAB2_LCD_SEP = " 00 02 ";
    KEYLAB2_LCD_END = " 00 F7";
 End
    
Function StringToHexString(str : String) Returns String
   var i : Integer
   result = "";

   For i=0; i<Length(str) ; i=i+1 Do
     result = result + ASCII_HEX_STRING[IndexOfSubstring(ASCII_STRING, CopySubstring(str,i,1), True)];
   End
End
    
Function Keylab2LCD(line0 : String, line1 : String)
    If Length(line0) > 16
	Then
		line0 = CopySubstring(line0, 0, 16);
    End
    line0 = StringToHexString(line0);
    
    If Length(line1) > 16
    Then
        line1 = CopySubstring(line1, 0, 16);
    End
    line1 = StringToHexString(line1);


    SM_CreateSysexFromString(SysEx, KEYLAB2_LCD_PRE + line0 + KEYLAB2_LCD_SEP + line1 + KEYLAB2_LCD_END); 
    SM_SendMidiOut(SysEx, Keylab2);
End

On Activate
    var s : String;
    s = "Rackspace:";
    Keylab2LCD(s, GetRackspaceName());
End
3 Likes