|
|
|
01-31-2016, 08:11 AM
|
#1
|
Human being with feelings
Join Date: Jan 2016
Posts: 16
|
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
|
|
|
01-31-2016, 10:48 AM
|
#2
|
Banned
Join Date: Sep 2015
Posts: 1,650
|
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.
|
|
|
01-31-2016, 04:40 PM
|
#3
|
Human being with feelings
Join Date: Jan 2016
Posts: 16
|
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?
|
|
|
02-01-2016, 05:49 AM
|
#4
|
Banned
Join Date: Sep 2015
Posts: 1,650
|
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.
|
|
|
06-01-2018, 11:59 PM
|
#5
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Quote:
Originally Posted by snooks
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
|
|
|
06-02-2018, 04:27 AM
|
#6
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by spk77
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?
|
|
|
06-02-2018, 05:10 AM
|
#7
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Quote:
Originally Posted by Lokasenna
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 - header data
- length data
- 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.
|
|
|
06-02-2018, 06:58 AM
|
#8
|
Human being with feelings
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
|
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.
|
|
|
06-02-2018, 07:16 AM
|
#9
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
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)
|
|
|
06-02-2018, 08:23 AM
|
#10
|
Human being with feelings
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
|
Quote:
Originally Posted by spk77
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.
|
|
|
06-02-2018, 02:08 PM
|
#11
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,333
|
It's not a good choice to put FXs with delay on Monitoring FX.
|
|
|
06-02-2018, 03:38 PM
|
#12
|
Human being with feelings
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
|
Quote:
Originally Posted by vitalker
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.
|
|
|
06-02-2018, 10:42 PM
|
#13
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Quote:
Originally Posted by James HE
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
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
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:
|
|
|
06-07-2018, 01:37 PM
|
#14
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
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);
}
|
|
|
06-08-2018, 01:52 PM
|
#15
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
gfx.getdropfile is a very nice function:
This thing isn't working yet.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 12:45 AM.
|