Old 01-17-2017, 12:04 PM   #1
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default Send MIDI messages

== edit 2017.01.19 ==
With Reaper 5.33pre1 and up, a simpler solution is now ready to use.

Head down to post #21 to find the script, readable and downloadable.

==========

Can we send midi messages without having to use OSCII-bot ?

I have to use an external program to send a specific midi message out from inside a LUA script to do what I want to do.

This sucks. Extra complexity. This is hardly time critical stuff, so LUA would be fine, or EEL if necessary.

OSCII-bot is seriously complex because it supposes the user has a lot of information up front.

So, can we do this yet ? We can send OSC messages, but MIDI ?
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom

Last edited by airon; 01-19-2017 at 01:55 AM.
airon is online now   Reply With Quote
Old 01-17-2017, 12:54 PM   #2
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 1,221
Default

Only reaper.StuffMIDIMessage(), I guess. And it is only for some non-critical stuff in timing context (ReaScript defer loop refresh rate is about 30 times a second).

Here is examples from me and Lokasenna:
http://forum.cockos.com/showthread.php?t=185976
http://forum.cockos.com/showthread.php?t=185358
__________________
SoundCloud | MPL Scripts / ReaPack | Donate

Last edited by mpl; 01-17-2017 at 01:00 PM.
mpl is offline   Reply With Quote
Old 01-17-2017, 12:56 PM   #3
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 9,047
Default

Where do you want to send it? You can generate track MIDI using a JS, or use ReaScript to stuff a MIDI message into the virtual keyboard queue, which will then go wherever the virtual keyboard is routed.
schwa is offline   Reply With Quote
Old 01-17-2017, 01:01 PM   #4
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

I'm looking to change banks of control knobs via another controller or keyboard shortcuts, which requires sending a midi message.

I have two Midi Fighter Twister units, which both have four banks of 4x4 knobs. I change that bank with a midi message. This is a control thing.

Right now I'm doing this but the device number changes:
Code:
local function SendMIDI(MIDI_port,MIDI_channel,MIDI_note,MIDI_velocity)
    cmdline =  [["]] .. reaper.GetResourcePath() .. [[\scripts\sendmidi.exe" --out ]] .. MIDI_port .. [[ --note-on ]] .. MIDI_channel .. [[ ]] .. MIDI_note .. [[ ]] .. MIDI_velocity
    reaper.ExecProcess(cmdline,-2)
end
device = 19 -- use lsmidiouts.exe to scan for which port your device is located at

bank = 2 -- 0=bank 1 up to 3=bank4

SendMIDI(device,3,bank,127)
Sendmidi.exe is a simple commandline tool. But of course that fails a lot as I have to change the device number after each reboot. Thus I never use it.

Since Reaper sees these devices, I presumed it could address them. I'm just not sure how. A script would be ideal because I can bind it to anything.

The commands stem from this manual from DJ Techtools on page 8.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom
airon is online now   Reply With Quote
Old 01-17-2017, 01:06 PM   #5
snooks
Human being with feelings
 
Join Date: Sep 2015
Posts: 1,161
Default

You can use the script to insert a custom JS effect that can transmit the messages. Have a look here to see it being done in reverse where the script gets notes from the effect....

https://github.com/Lazzle/ReaMIDI/bl...M%20Delete.lua
snooks is offline   Reply With Quote
Old 01-17-2017, 01:23 PM   #6
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 9,047
Default

You could also set up a dummy track with an external MIDI send to the device, have that track receive input from the virtual keyboard, and use StuffMIDIMessage from a ReaScript.
schwa is offline   Reply With Quote
Old 01-17-2017, 01:24 PM   #7
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 1,221
Default

If I understood right, you need to:
  • Add new track
  • Turn On monitor input
  • Set input to channel 4 of virtual keyboard
  • Send MIDI output from this track to your device (Routing>MIDI Hardware Output)
  • this Lua code

Code:
midi_channel = 4
bank = 1
reaper.StuffMIDIMessage( 0, -- virtual keyboard
                        '0x9'..string.format("%x", midi_channel-1), -- NoteOn
                        bank-1, -- MIDI note
                        127)  -- MIDI velocity
__________________
SoundCloud | MPL Scripts / ReaPack | Donate

Last edited by mpl; 01-17-2017 at 01:30 PM.
mpl is offline   Reply With Quote
Old 01-18-2017, 06:51 AM   #8
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

Ok, let me give this stuff a try. Sound jolly complicated, but it might be simple once it's setup.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom
airon is online now   Reply With Quote
Old 01-18-2017, 08:18 AM   #9
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

Quote:
Originally Posted by mpl View Post
If I understood right, you need to:
  • Add new track
  • Turn On monitor input
  • Set input to channel 4 of virtual keyboard
  • Send MIDI output from this track to your device (Routing>MIDI Hardware Output)
  • this Lua code

Code:
midi_channel = 4
bank = 1
reaper.StuffMIDIMessage( 0, -- virtual keyboard
                        '0x9'..string.format("%x", midi_channel-1), -- NoteOn
                        bank-1, -- MIDI note
                        127)  -- MIDI velocity
This lua code ? Triggered how ?

I probably need more details, since I deal with midi only when working with control hardware.

If this has to go out through a selected track, it will not be useful, since I'll be operating all kinds of plugins on one or more tracks at that time, and should not change track selection in the middle of that. Plugin windows will pop in and out of existence which slows everything down. I'll lose my temporary track selection unless I restore the track selection at the end of this.

Or is this a method that can operate independently of track selection ?

-edit-
Ok, I got the virtual midi keyboard to work, sending the lowest notes on the keyboard to trigger bank changes on the Twister. I need to keep that track armed, which may be a crutch. We'll see.

I keep one track around per Twister to which I route the virtual keyboard midi data, so I switch banks with one message.

Now I'll go and see what script might do. I hope it doesn't just work on a selected track.
-Edit 2-
Ok, the script works fine as well. I've created one script per bank. I'll save this 3-track set as a track template. The real bonus is that don't need to select a different track as far as I can tell right now.

One bit of advice for the programmers here. Assume the person you're sending your help to knows nothing. In fact it's a golden rule in post production.

@Schwa : Shouldn't this be easier ? Who aside from me, or folks like MPL is ever going to do all this ?
Thank you gentlemen. At least I have an option now.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom

Last edited by airon; 01-18-2017 at 08:41 AM.
airon is online now   Reply With Quote
Old 01-18-2017, 08:39 AM   #10
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 3,956
Default

You're sending a MIDI message through Reaper's Virtual MIDI Keyboard, which any track can use as its MIDI input (or if they're set to All MIDI Inputs).

Here's my Chord Helper script: https://github.com/ReaTeam/ReaScript...d%20Helper.lua

Line 3502:
Code:
local function update_MIDI_queue()
	
	-- Check if any pending notes are ready
	local time = reaper.time_precise()
	for note, stamp in pairs(notes_pending) do
		if time >= stamp[1] then
					
			reaper.StuffMIDIMessage(0, 0x90 + chan, note, vel)
			notes_timing[note] = time + stamp[2]	
			notes_pending[note] = nil
			
		end
	end
		
	-- Check if any active notes are finished
	for note, stamp in pairs(notes_timing) do
		if time >= stamp then

			reaper.StuffMIDIMessage(0, 0x80 + chan, note, vel)
			notes_timing[note] = nil
		
		end
	end
end
Elsewhere in the script (function at line 3253 if you're interested) I put MIDI note numbers into an array, notes_pending, along with calculated times for the Note On message if I want to play an arpeggio.

The code above checks to see if any notes in the array are due to be played or stopped, then uses reaper.StuffMIDIMessage to push them into the VMK. A message value of 0x90 + note is Note On, and 0x80 + note is Note Off.

chan and vel are defined elsewhere, but they just use the usual 0-15 and 0-127 values.

Quote:
@Schwa : Shouldn't this be easier ? Who aside from me, or folks like MPL is ever going to do all this ?
I do have an FR thread open that would make things easier for my purposes: http://forum.cockos.com/showthread.php?t=185366 - your idea here is a little more complicated, though, so I'm not sure if it would help.

It'd be easy enough to write a wrapper function that just takes note, chan, vel, length and handles the message stuff for you.
Lokasenna is online now   Reply With Quote
Old 01-18-2017, 09:02 AM   #11
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

I can think of a few things to do, but they may be impractical.

The limitation of one midi hardware out per track is one thing. I'm stacking tracks this way and have to arm something to keep this going.

This all points to Reaper distinct lack of midi feedback, i.e. you either write a control surface plugin or hack around like we are here today(thank you all the same). Quite a few DAWs use Javascript or Python to let users receive and send midi data.

We do have OSCII-bot but I find it very hard to understand. The SWS extension is easy to install and operate. OSCII-bot is not. Control scripts for Ableton Live are probably hard to create but easy to install. Maybe Bitwig does it well and some ideas can inspire something built in to Reaper.

Right now I need to:
  • Have one track with the Virtual Keyboard as an input, with monitoring activated, the track armed, and channel 4 on the VK selected.

  • If one device is to be addressed, the MIDI HARDWARE SEND can be established on the same track.

  • If more than one devices are to be addressed, a track for each device must be created with a MIDI HARDWARE SEND each that addresses each device in turn

  • A script(Lua/EEL/Python/C++) must send a specific midi message to the Virtual Keyboard via the API function StuffMIDIMessage. One script per value change. All this so messages can be fired off by Reapers custom triggers such as keyboard shortcuts, midi notes/cc or OSC messages. There is no alternative that I know of.


Anyone have ideas on how to address this ? Is letting Reascripts send data directly to devices even possible with the current code base ? When I see what MPL, Eugen and LBO(to name a few) are doing in Lua/EEL, I'm wondering whether the limitation of keeping MIDI devices out of the hands of Reascripters is still justified and should at least be looked at for improvement.


I'd like to keep a LUA/EEL script running that simply reserves and is sent a couple of MIDI triggers when they happen and fires off some messages. I'd be able to hack together a load of stuff that way.

How about scripts being able to present trigger slots for assignment in the action list ? That way we don't have to write a script per thing we want to trigger.

And access to MIDI devices.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom

Last edited by airon; 01-18-2017 at 09:11 AM.
airon is online now   Reply With Quote
Old 01-18-2017, 09:05 AM   #12
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 9,047
Default

Quote:
Originally Posted by airon View Post
Shouldn't this be easier ? Who aside from me, or folks like MPL is ever going to do all this
I don't think there's any reasonable UI that would cover the use case of "send arbitrary MIDI messages to arbitrary hardware," so a script has to be involved in some way, and the track is required to make the hardware addressable by the project.

The only way I can think of that this could be simpler would be to extend StuffMIDIMessage to allow routing to any addressable device that is not in use by the project, but honestly I don't think that use case qualifies for the question "shouldn't this be easier."
schwa is offline   Reply With Quote
Old 01-18-2017, 09:10 AM   #13
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 9,047
Default

Quote:
Originally Posted by airon View Post
channel 4 on the VK selected.
Did the channel 4 specification come from anything other than MPL's example, which I think was just specifying the channel to show that it was possible?

Quote:
Originally Posted by airon View Post
One script per value change
That script could be as fancy as it wants to be. The script could present a toolbar or menu of messages. If you have a set of tracks each addressing different hardware, you could use a different MIDI channel for each one and the script could present UI for selecting the destination as well.
schwa is offline   Reply With Quote
Old 01-18-2017, 09:19 AM   #14
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 3,956
Default

Quote:
Originally Posted by airon View Post
  • Have one track with the Virtual Keyboard as an input, with monitoring activated, the track armed, and channel 4 on the VK selected.
You can have the track set to All MIDI Inputs, and use whatever channel you want. You can also have the script take care of the monitoring and arming automatically.

Quote:
I'd like to keep a LUA/EEL script running that simply reserves and is sent a couple of MIDI triggers when they happen and fires off some messages. I'd be able to hack together a load of stuff that way
JS effects are able to set up a global, shared memory space so different plugins can communicate. It would be nice if that functionality were extended to ReaScripts. (assuming it isn't already, don't think it is though)
Lokasenna is online now   Reply With Quote
Old 01-18-2017, 09:22 AM   #15
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

Quote:
Originally Posted by schwa View Post
Did the channel 4 specification come from anything other than MPL's example, which I think was just specifying the channel to show that it was possible?


That script could be as fancy as it wants to be. The script could present a toolbar or menu of messages. If you have a set of tracks each addressing different hardware, you could use a different MIDI channel for each one and the script could present UI for selecting the destination as well.
True. It'll clog up the track list, which is why I keep them invisible. If anyone clears the arming status, that thing has to be turned back on. I think it'll be ok for a small use like mine, but it makes me wary to use tracks like this. Points of failure are a concern and there are multiple here.

I've got a Novation Dicer and an X-Touch Mini. None of those buttons light up, except for the built in stuff like Dicers bank buttons.



I mention some ideas in the edits in my previous post, like scripts posting action list triggers(which would be actions themselves I guess).

The idea is to have multiple triggers being sent to a script, without the script having to care what triggered them. No extra input scans by a script.

Not sure how that would work though. All that to have scripts in the background be able to catch triggers.

I'd write something that looks at the currently selected plugin and light up an LED on a MIDI device as a result. Who knows. We might even do parameter feedback that way.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom
airon is online now   Reply With Quote
Old 01-18-2017, 11:18 AM   #16
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Germany
Posts: 2,511
Default

Quote:
Originally Posted by schwa View Post
use ReaScript to stuff a MIDI message into the virtual keyboard queue, which will then go wherever the virtual keyboard is routed.
Meaning you need to do a track and assign the virtual keyboard as a Midi input ?

This sounds rather queer.

-Michael
__________________
www.boa-sorte.de
mschnell is online now   Reply With Quote
Old 01-18-2017, 11:41 AM   #17
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 3,956
Default

Quote:
Originally Posted by mschnell View Post
Meaning you need to do a track and assign the virtual keyboard as a Midi input ?

This sounds rather queer.

-Michael
For like the fourth time, "All MIDI Inputs" works just as well.
Lokasenna is online now   Reply With Quote
Old 01-18-2017, 01:13 PM   #18
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

I do think we've made our point about sending midi data directly to devices. It's actually really cool to be able to do all this with the virtual midi keyboard.

Being able to address midi devices is a big thing. Speculation: some of of the script wizards here could perhaps even code stuff like we see in midi feedback scripts similar to Ableton Live and Bitwig. I'd certainly look in to that, though I doubt I can do stuff as well as MPL or LB0 for example.

Why is that useful/cool ? All my LED rings go unused, except on the devices I almost never use for that purpose, the Mackie Control Universal.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom
airon is online now   Reply With Quote
Old 01-18-2017, 02:15 PM   #19
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: The vast, frozen wasteland of western Canadia.
Posts: 3,956
Default

I'm sure you've seen it, but just in case - you might want to have a look at today's new prerelease version.

No help for my FR though
Lokasenna is online now   Reply With Quote
Old 01-18-2017, 06:12 PM   #20
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

Thanks for the tip. Now I'm going to dream about this stuff.

I still have to find out how to use the GetMIDI.... number and name commands.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom
airon is online now   Reply With Quote
Old 01-19-2017, 01:30 AM   #21
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

And here it is.

It's pretty custom, but should be adaptable with little work.

The code is below. You can download the script here:
http://stash.reaper.fm/29565/mft_bankcontrol_1.lua

There's some extra config information on the page for the downloadable version.

target_devices are what I called my two Midi Fighter Twisters. I have not found a way to hack the firmware yet, to give them unique names out of the box.

Code:
-- Send midi note message to target device(s)
-- requires Reaper 5.33pre1 or higher

-- Target Configuration --
local midichan = 4
local mftbank = 1 -- Midifighter Twister Bank
local vel = 127
local target_devices = { "Twister1" , "Twister2" }
--Target Configuration end --

msg_flag = false;
function msg(val) ; if msg_flag then ; reaper.ShowConsoleMsg(tostring(val).."\n");end;end
function msgclr() ; if msg_flag then ; reaper.ShowConsoleMsg("");end;end
local i,k = 0 , 0
local target_devnum = {} -- array to collect device numbers

local mdev_outno = reaper.GetNumMIDIOutputs() -- grab number of midi outputs in Reaper
msgclr()
msg("Midi Outs Reaper: " .. mdev_outno)
msg("Stepping through devices...")

for k=1, #target_devices, 1 do
  for i=1, mdev_outno, 1 do
    retval, mdev_name = reaper.GetMIDIOutputName(i, "")
    if retval then
      if string.find(mdev_name,target_devices[k]) then -- check for target device name(s)
        target_devnum[k] = i -- add device number to list
        msg("Device found. No." .. i .. " " .. mdev_name .." matches " .. target_devices[k])
      end
    end
  end
end
for i=1, #target_devnum, 1 do
  reaper.StuffMIDIMessage( target_devnum[i]+16,
                           '0x9'..string.format("%x", midichan-1), -- NoteOn
                            mftbank-1, -- MIDI note (bank-1 for MidiFighterTwister)
                            vel)  -- MIDI velocity
                            -- later we'll add a command execution list
  retval, mdev_name = reaper.GetMIDIOutputName(target_devnum[i], "")
  msg("Sent note to " .. mdev_name)
end
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom

Last edited by airon; 01-19-2017 at 01:58 AM.
airon is online now   Reply With Quote
Old 01-19-2017, 07:51 AM   #22
lou latch
Human being with feelings
 
Join Date: Feb 2015
Posts: 66
Default

Excuse my uninformed question, but does that mean there is the possibility to directly control plugins with a midi controller and get feedback (on led rings, for example)? In a somehow easy way (i'm not into writing scripts myself)?
lou latch is offline   Reply With Quote
Old 01-19-2017, 03:41 PM   #23
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

I have managed to address the LED rings on my MFT unit, though only on one of them.

The question is whether I can check what controls are mapped to anything. I don't know right now.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom
airon is online now   Reply With Quote
Old 01-19-2017, 03:51 PM   #24
lou latch
Human being with feelings
 
Join Date: Feb 2015
Posts: 66
Default

...that sounds promising, cool!
It's a shame i can't support you get this sorted, i have no clue about implementing stuff like this.

thank you!
lou latch is offline   Reply With Quote
Old 01-20-2017, 06:18 AM   #25
airon
Human being with feelings
 
airon's Avatar
 
Join Date: Aug 2006
Location: City
Posts: 9,459
Default

Scrap that. One small mistake fixed and it all works.

So, I can address the two Twisters without problems.
__________________
Dialogue/FX Editor & Re-Recording Mixer
Using Latch Preview
"My ego comes pre-shrunk" - Randy Thom

Last edited by airon; 01-20-2017 at 06:37 AM.
airon is online now   Reply With Quote
Old 01-23-2017, 10:53 AM   #26
fundorin
Human being with feelings
 
fundorin's Avatar
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 83
Default

I'm also interested if this new API function will allow user to have midi feedback to the controller.
I'm also interested,if SYSEX messages are supported or not.
fundorin 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 03:37 PM.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.