Old 01-31-2016, 08:11 AM   #1
mikechr
Human being with feelings
 
Join Date: Jan 2016
Posts: 16
Default Send SYSEX message from LUA script

I would like to generate and send sysex MIDI messages from Reaper using an LUA function. FYI: This is to control a custom synth I’m designing and the message contains the mute status of each of the MIDI tracks. I do not want to embed the message in a track so I do not think that MIDI_SetTextSysexEvt() is what I want. I’ve seen the midisend_buf() function that is described in the JSFX API. Can midisend_buf be called from an LUA script? Is there a different avenue? A call into a C function?
Thanks
mikechr is offline   Reply With Quote
Old 01-31-2016, 10:48 AM   #2
snooks
Banned
 
Join Date: Sep 2015
Posts: 1,650
Default

If you want to use Lua (or EEL), the only option is StuffMIDIMessage, which works with 3 byte messages. I don't know if you could do several in a row for your SysEx message. This puts messages into the Virtual MIDI Keyboard queue, which means a track would have to be armed and routed to your synth.

The other options are to use a companion JSFX and either have preset SysEx messages stored in the code and triggered by having the Lua script change a trigger parameter, or to give it messages via parameter changes. Again this would require a track.

I remember somebody had MIDI stuff working in Python using external libraries, although that's not something I'd be keen on these days.
snooks is offline   Reply With Quote
Old 01-31-2016, 04:40 PM   #3
mikechr
Human being with feelings
 
Join Date: Jan 2016
Posts: 16
Default

I have the StuffMIDIMessage working and its an option.

I would need a track to take advantage of the JS midisend_buf facility? Can you think of any examples I can look at?

Another option I am considering is to use EEL TCP to send messages via a socket. Its a nice general purpose solution. Are there any hidden issues here?

Why is this such a challenge? Are Reaper's architects concerned with scripts messing up devices by interleaving MIDI streams?
mikechr is offline   Reply With Quote
Old 02-01-2016, 05:49 AM   #4
snooks
Banned
 
Join Date: Sep 2015
Posts: 1,650
Default

Re examples, the pioneer of that technique is eugen2777 and the Retrospective Record JS/ReaScript combo...

http://forum.cockos.com/showthread.php?t=168855

I've never used EEL socket stuff so couldn't tell you.

It would be nice to be able to inject MIDI into anything, although since ReaScript isn't a real-time/sample accurate thing - being called roughly 40 times a second - it's not really suitable for most applications. It would be good for this type of purpose though.
snooks is offline   Reply With Quote
Old 06-01-2018, 11:59 PM   #5
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by snooks View Post
If you want to use Lua (or EEL), the only option is StuffMIDIMessage, which works with 3 byte messages. I don't know if you could do several in a row for your SysEx message.
Unfortunately this doesn't seem to work. This is frustrating...
1. I'm trying to store Kemper rig data (sysex) to tracks - It's possible from Lua but not possible from JSFX
2. Send data back to Kemper when needed. (I figured out how to parse needed data from .kipr files) - It's possible from JSFX but not possible from Lua
spk77 is offline   Reply With Quote
Old 06-02-2018, 04:27 AM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Quote:
Originally Posted by spk77 View Post
Unfortunately this doesn't seem to work. This is frustrating...
1. I'm trying to store Kemper rig data (sysex) to tracks - It's possible from Lua but not possible from JSFX
2. Send data back to Kemper when needed. (I figured out how to parse needed data from .kipr files) - It's possible from JSFX but not possible from Lua
Damn you, I was going to try making a Kemper script... whenever I get some time with my Kemper again.

For #2, does it not work if you stuff a message using the Virtual MIDI Keyboard, with a track armed, and a hardware output on that track?
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 06-02-2018, 05:10 AM   #7
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Lokasenna View Post
Damn you, I was going to try making a Kemper script... whenever I get some time with my Kemper again.

For #2, does it not work if you stuff a message using the Virtual MIDI Keyboard, with a track armed, and a hardware output on that track?
Please try


I think it could work like this (very simplified example):
1. store kipr data to track(s) using Lua (read kipr file, use setextstate, store track GUID etc.)
2. create a JSFX with one slider (read stored data from Lua and pass the data to this JSFX using reaper.TrackFX_SetParam. When "0xF7" is send from Lua, the JSFX should send the complete sysex message to MIDI out. Repeat until all messages are processed )



About kipr file...
Here's a start of a kipr file:
4B 54 68 64 00 00 00 06 00 00 00 01 01 E0 4B 54 72 6B 00 00 15 6A 00 F0 1F 00 20 33 00 00 03 00 00 01 53 50 4B 37 37 20 42 55 47 33 33 33 20 4C 65 61 64 20 36 33 00 F7 00 F0 10 00 20 33 00 00 03 00 00 02 53 50 4B 37 37 00 F7 00 F0 1E 00 20 33 00 00 03 00 00 03 32 30 31 37 2D 30 35 2D 32 37 20 31 33 3A 31 39 3A 32 30 00 F7 00 F0 26 00 20 33 00 00 03 00 00 04 4A 6F 79 6F 20 4F 44 20 2D 20 44 72 69 76 65 30 20 56 6F 6C 34 20 54 6F ...

red = kipr file header
green = start of actual data
(blue = length of current message - this should be excluded when sending data to kemper) See post #14
olive = rest of the current message
lime = separator between messages

When sending to Kemper, skip
  1. header data
  2. length data
  3. separator data

I think "stuffmididata" would not work with this. (At least I couldn't get it to work)

Last edited by spk77; 06-07-2018 at 01:42 PM.
spk77 is offline   Reply With Quote
Old 06-02-2018, 06:58 AM   #8
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

Instead of having to have a track that has to be armed in the project, there is a trick you can use.

Put your JS in the MONITOR FX and then send to your MIDI Hardware out using ReaInsert. This means it's always there. persists for every project, etc.



The MIDI cc_sender and the Launch_MIDI in my chain here are kind of doing exactly what you are trying to do here. They are triggered via a script (or just send midi when I open REAPER) to MIDI hardware.
James HE is offline   Reply With Quote
Old 06-02-2018, 07:16 AM   #9
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Thanks James HE! I'm going to test that.

Here's a quick test - send sysex from Lua to JSFX to MIDI out
(I don't have my Kemper at home, I still have to test it with real rig data)
spk77 is offline   Reply With Quote
Old 06-02-2018, 08:23 AM   #10
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

Quote:
Originally Posted by spk77 View Post
Thanks James HE! I'm going to test that.
Great!

Just a note in case you didn't know this, as I don't think it's even documented except in some forum post from Justin - and I can't even find the post.

To access the monitor FX via ReaScript, you use the Mastertrack, but the slots are bit shifted up i believe.

To get and manipulate the effect I use something like the code below (in Reascript EEL) - might be an easier way in .lua since it seems easier to deal with strings. You might find a better way in EEL as well.

Code:
#FXNAME = "your path/your effect name"; 


//Get where in the chain the Monitor FX is
    mt=GetMasterTrack(0);    
    i=0;
    while(!found) (
      TrackFX_GetFXName(mt, 0x1000000+i, #GetName);
      !strcmp(#GetName,#FXNAME) ? ( slot=i; found=1; );
      !strcmp(#GetName,"") ? (found=1;  slot=-1);
      i+=1;
    );
    
    TrackFX_GetFXName(mt, 0x1000000+slot, #GetName);
    strcmp(#GetName,#FXNAME) ? found=0;

//then you change parameters with -

TrackFX_SetParam(mt, 0x1000000+slot, param, val);

Last edited by James HE; 06-02-2018 at 08:32 AM.
James HE is offline   Reply With Quote
Old 06-02-2018, 02:08 PM   #11
vitalker
Human being with feelings
 
vitalker's Avatar
 
Join Date: Dec 2012
Posts: 13,333
Default

It's not a good choice to put FXs with delay on Monitoring FX.
vitalker is offline   Reply With Quote
Old 06-02-2018, 03:38 PM   #12
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

Quote:
Originally Posted by vitalker View Post
It's not a good choice to put FXs with delay on Monitoring FX.
because of the lack of PDC? I suppose that's true.

You have to deal with PDC within the code itself in JSFX anyway and it's very unlikely that the effect would need PDC. The MIDI gizmo here is just acting as a courier in a way between a script and a piece of Hardware.


@SPK77


You could also do something crazy here just with JSFX. I'm guessing each of those hex values is a parameter? SO you could pretty much tie all those parameters to sliders (or serialized values if you need more than 64 parameters) then concatenate all those values as a string and send it to the hardware - you could just have a JSFX that could even save and store presets for the hardware this way.

^ that's probably much harder to code than whatever you are currently working on via ReaScript, but something like that could be an option.
James HE is offline   Reply With Quote
Old 06-02-2018, 10:42 PM   #13
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by James HE View Post
Great!

Just a note in case you didn't know this, as I don't think it's even documented except in some forum post from Justin - and I can't even find the post.

To access the monitor FX via ReaScript, you use the Mastertrack, but the slots are bit shifted up i believe.

To get and manipulate the effect I use something like the code below (in Reascript EEL) - might be an easier way in .lua since it seems easier to deal with strings. You might find a better way in EEL as well.

Code:
#FXNAME = "your path/your effect name"; 


//Get where in the chain the Monitor FX is
    mt=GetMasterTrack(0);    
    i=0;
    while(!found) (
      TrackFX_GetFXName(mt, 0x1000000+i, #GetName);
      !strcmp(#GetName,#FXNAME) ? ( slot=i; found=1; );
      !strcmp(#GetName,"") ? (found=1;  slot=-1);
      i+=1;
    );
    
    TrackFX_GetFXName(mt, 0x1000000+slot, #GetName);
    strcmp(#GetName,#FXNAME) ? found=0;

//then you change parameters with -

TrackFX_SetParam(mt, 0x1000000+slot, param, val);
That will be useful, thanks again!

Quote:
Originally Posted by vitalker View Post
It's not a good choice to put FXs with delay on Monitoring FX.
Delay shouldn't be a problem...I really wish that we could send sysex from ReaScript StuffMIDIMessage for controlling external MIDI hardware. Would be so much easier.

Quote:
Originally Posted by James HE View Post
because of the lack of PDC? I suppose that's true.

You have to deal with PDC within the code itself in JSFX anyway and it's very unlikely that the effect would need PDC. The MIDI gizmo here is just acting as a courier in a way between a script and a piece of Hardware.


@SPK77


You could also do something crazy here just with JSFX. I'm guessing each of those hex values is a parameter? SO you could pretty much tie all those parameters to sliders (or serialized values if you need more than 64 parameters) then concatenate all those values as a string and send it to the hardware - you could just have a JSFX that could even save and store presets for the hardware this way.

^ that's probably much harder to code than whatever you are currently working on via ReaScript, but something like that could be an option.
There's over 800 parameters
Then there's rig specific information (rig name, amp name, cab name etc.) included in "kipr" files:

spk77 is offline   Reply With Quote
Old 06-07-2018, 01:37 PM   #14
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

It seems that sending too much data per block will freeze the Kemper. I guess all sysex data from a "kipr" file should be stored to a JSFX buffer. It would be easier to control how many bytes@block is sent to Kemper.



I noticed that data length of a sysex message is stored as a series of bytes which is called a variable length quantity (thanks Damian Greda! https://www.thegearpage.net/board/in...ditor.1936694/)

Code:
F0 1A 00 20 33 00 00 03 00 00 01 53 50 4B 37 37 20 47 4D 33 36 47 61 69 6E 39 00 F7
Code:
F0 81 14 00 20 33 00 00 02 00 33 00 00 00 00 00 00 01 00 00 7F 7F 40 00 40 00 60 00 40 00 40 00 7F 7F 00 00 00 02 00 00 00 00 00 00 00 00 40 00 00 00 00 00 40 00 40 00 00 00 00 00 7F 7F 40 00 40 00 00 01 00 00 00 00 00 00 40 00 40 00 40 00 40 00 40 00 40 00 40 00 40 00 40 00 40 00 40 00 40 00 22 2F 40 00 56 1D 40 00 3A 2E 40 00 40 00 4A 1C 40 00 40 00 40 00 40 00 00 00 00 40 00 40 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 40 00 00 00 7F 7F F7
Here's how to read the length: http://midi.teragonaudio.com/tech/midifile/vari.htm
(I just converted this to Lua)
Code:
unsigned long ReadVarLen()
{
    register unsigned long value;
    register unsigned char c;

    if ( (value = getc(infile)) & 0x80 )
    {
       value &= 0x7F;
       do
       {
         value = (value << 7) + ((c = getc(infile)) & 0x7F);
       } while (c & 0x80);
    }

    return(value);
}
spk77 is offline   Reply With Quote
Old 06-08-2018, 01:52 PM   #15
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

gfx.getdropfile is a very nice function:



This thing isn't working yet.
spk77 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:24 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.