11-05-2017, 04:41 AM | #1 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
Midi <-> OSC
Hi experts,
I have done a rather complex set of JSFX plugins to control the sound "patches" loaded in Reaper for live playing by a motor-fader enabled controller board ("XTouch Compact"). Hence the JSFX system does bidirectional communication with the controller via Midi. Now I'd like to add communication with a mixer device ("XR 18") coupled via OSC (over WiFi) to display and modify the mixer settings on the controller board. Right now, I plan to do a Python program, as same needs to be able to find the mixer via OSC and register for being sent any values modified by other instances also attached to same. A Friend of mine already did and successfully uses such a Python program, communicating with the XR18 via OSC and with some hardware device via Midi. I wonder if it might be viable to use OSCIIbot with some EEL programming instead (as I am rather experienced with EEL but not with Python yet). Did anybody already successfully use OSCIIbot and can provide some comments ? -Michael |
11-10-2017, 03:20 PM | #2 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
I've used OSCII-bot for osc / midi stuff, what'cha need?
|
11-10-2017, 05:48 PM | #3 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
Thanks for answering, Justin !
There is a discussion I initiated in the OSCIIbot subforum. For getting started I'd like do display part of the current mixer state. So I need to "attach" to a mixer (XR18) via OSC via WIFI. For this I of course need to provide the IP-Address and the port. I understand this is done in the EEL code. OK for now, but in the end I would like to read it from a config file. (I know that OSCIIbit can read files, and I suppose I'll be able to make use of the content.) After that we need to send "subscribe"/"register" messages to the mixer in regular time intervals to have it send us any values of a set of parameters on the spot and/or at any time they are changed by other instances. I understand this is an OSC standard method and supposedly also done when OSCIIbots connects to Reaper via OSC (wich AFAI understand is the way OSCIIbot is mostly used). Unfortunately I failed to find any examples of such OSCIIbot ELL program code. Thanks again, -Michael Last edited by mschnell; 11-11-2017 at 02:08 AM. |
11-11-2017, 04:19 PM | #4 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
Justin,
I was able to set up an OSCIIbot script correctly (details see thread in the OSCIIbot forum). Code:
@input XT_M_IN MIDI "loopMIDI Port" //in quotation marks-name of midi port used in Windows @input XR18in OSC "*:10024" @output XR18out OSC "192.168.1.1:10024" Code:
C:\Users\mschnell\AppData\Roaming\oscii-bot\test1.txt Listening on '*:10024' 2 inputs, 1 outputs Total: 1 scripts, 2 inputs, 1 outputs Using Wiresshark I found that the XR18 responds correctly to (e.g.) a "status" command. But a printf() in the @oscmsg section in the script does not output any text. what am I doing wrong ? -Michael |
11-12-2017, 12:28 AM | #5 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
As I see in WireShark, in fact (IMHO rather decently), the OSC device answers to an OSCIIbot message by an UDP/OSC block directed to the port number given as a sender in the received block.
If in OSCIIbot the OSC input and output devices are independent (as it seems from EEL code), how can the @output as a sender port address provide the port number the @input is initiated to listen on ? Seemingly the sender port number is defined (by Windows?) as some random number when @output is called. Using Wireshark, I can see an new number with any start of OSCIIbot. I checked that it's not possible to use an @input device do send to: @input XR18out OSC "192.168.1.1:10024" //trying to define the target address here results in "Error listening for '192.168.1.1:10024'" and oscsend(): output device 0.000000 invalid OTOH @output XR18out OSC "192.168.1.1:10024" @input XR18out OSC "*:10024" results in Warning: device name 'XR18out' already in use, skipping @input line -Michael Last edited by mschnell; 11-12-2017 at 01:50 AM. |
11-12-2017, 07:18 AM | #6 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
Ah yeah, I don't think we ever added bidirectional OSC support for this scenario, let me see if I can do that now.
|
11-12-2017, 08:59 AM | #7 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
http://www-dev.cockos.com/oscii-bot/
Try this version I just made, 0.4. In this, you can receive OSC messages back from the device that you sent to (also, you can send messages on OSC receives, which go to the last address that sent to you). |
11-12-2017, 03:23 PM | #8 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
WOW !!!
That was fast !! Just 12 hours after I found that the previous version would not work for me ! I'll test ASAP. Thanks a lot, -Michael |
11-12-2017, 03:28 PM | #9 | |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
Quote:
Now I suppose I can easily implement the dialogue. -Michael |
|
11-12-2017, 04:11 PM | #10 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
I did some tests.
I can send and receive messages like "/status" to/from the XR18. I can send the message "/xremotenfb" to the XR18 and then OSCIIbot receives lots of messages when I attach to the XR18 with the Editor provided by Behringer and move a fader. The message received in oscstr is e.g. "/rtn/aux/mix/06/level" and with oscparm(0,'f') I can get a value between 0.0 and 1.0 which seems perfectly correct ! Thanks again !!!! -Michael Last edited by mschnell; 11-12-2017 at 10:33 PM. |
11-12-2017, 04:12 PM | #11 |
Human being with feelings
Join Date: Nov 2015
Location: Cologne
Posts: 1,636
|
I'm not into programming at all. But does that mean bi-directional OSC communication is working from now on?
|
11-12-2017, 06:50 PM | #12 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
|
11-13-2017, 02:53 AM | #13 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Hi, Justin. Could you, please, make version 0.5 with SYSEX support?
And, maybe, Lua, instead of EEL2? Last edited by fundorin; 11-13-2017 at 04:04 AM. |
11-13-2017, 03:28 AM | #14 |
Human being with feelings
Join Date: Nov 2015
Location: Cologne
Posts: 1,636
|
|
11-13-2017, 10:08 AM | #15 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
|
11-13-2017, 11:37 AM | #16 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
I need middleware (oscii-bot) to send SYSEX to the controller, so it'll display text on built-in LCD. But what's also important is that the controller itself sends\receives sysex commands during startup and while changing modes, so the host would know about the current state of the controller and the controller knows that connection with the host isn't broken. Otherwise it will eventually show "Automap is OFFLINE" on the LCD. |
|
11-13-2017, 02:33 PM | #17 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
Give 0.5 a try, http://www-dev.cockos.com/oscii-bot/
Untested, but it might work! The docs are updated, but to summarize: Receiving SysEx: @midimsg, msg1/msg2/msg3 will be 0, oscstr will be set to the SysEx data (oscstr will be -1 if it's not a sysex) Sending SysEx: use midisend_str(device,#sysexdata_as_string); String reference: https://www.reaper.fm/sdk/js/strings...s_string_funcs useful functions for accessing binary strings include str_getchar() and str_setchar(). There's no point in doing Lua support, IMO, one easily could port it, but with great tedium. |
11-13-2017, 03:03 PM | #18 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
P.S. The beauty of Lua is in simplicity. I kinda broke my head trying to count memory cells to allocate data in EEL2. |
|
11-13-2017, 03:44 PM | #19 |
Administrator
Join Date: Jan 2005
Location: NYC
Posts: 15,721
|
You can use strings, which might make a lot of things easier...
|
11-13-2017, 10:34 PM | #20 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
That is great !
Now I hope that a library of user OSCIIbot scripts will emerge supporting e.g. lots of controller boards. Maybe the title of the JSFX-/REA- script forum should be modified to have OSCIIbot scripts issues be discussed there, too ... -Michael Last edited by mschnell; 11-13-2017 at 10:40 PM. |
11-14-2017, 05:54 AM | #21 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
-del-
|
11-14-2017, 12:59 PM | #22 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
I'm not sure that I understood correctly. For example, I need to store track names/plugin names/parameters, so that when I'm switching between different modes of the controller, the names to display on LCD would be taken out from memory/script and not from Reaper itself, via "refresh all consoles" action.
Do you suggest using strings instead of arrays or memsets for this task? |
11-14-2017, 03:21 PM | #23 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Fundorin,
OSCII-bot gives 1024 "string slots" and named string variables that can be used more flexibly for storage for the LCD display's contents than [] style arrays & memory offsets See the "strings" section of http://www-dev.cockos.com/oscii-bot/oscii-bot-doc.html and this (jsfx) thread on same topic https://forum.cockos.com/showthread.php?t=132630 There's probably some JSFX EEL2 code examples to be found too using strings like this. Good luck with Sysex! |
11-14-2017, 05:38 PM | #24 | ||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
In normal languages, it's possible to use multi-dimensional arrays (or tables, in Lua's case). So, there would be no problem to store all that info from Reaper and update it, when needed, using arrays. Please, tell me the proper way to use strings for that kind of task. As I said before, the alternative would be refreshing the console each time when the mode is switched, which can happen quite often. For example, the console is in mixer mode and I want to temporarily switch it into FX mode to change compressor's ratio on currently selected track. I imagine pressing and holding FX button on the console, turning the first encoder, is mapped to ratio, then just release FX button and I'm back in mixer mode. I need to see FX parameters on LCD to know which encoder should be turned. From my previous experience, updating the whole console with the corresponding action can take up to one second with default .reaperOSC file and most of this data would be irrelevant for the described task. Storing that data in script seems like a reasonable alternative and usually strings aren't the best way of storing multiple types data. Quote:
Thanks. I hope oscii-bot won't crash, like it celphor's fork did! |
||
11-14-2017, 10:44 PM | #25 | |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
Quote:
I'll give that a try . -Michael |
|
11-14-2017, 10:47 PM | #26 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
|
I suppose it's not handy (and of course not possible) to store all theses strings in string slots.
I think you should construct the string to be sent on the fly whenever it is to be sent from just some simple (partial) strings, some mall arrays of strings, and numbers by using sprintf(). OTOH, it even should be possible to on the fly read a string from line number n in a file, after calculating n in the program from the multiple "dimensions" of the task definition. Obviously mode switching of such a console is a very sensible application for the new OSCIIbot. Unfortunately the Controller I use (XTouch compact) does not feature any text display BTW.: does anybody know a Midi "controller board" that provides nothing but a text display ? Id like to add such to my setup. Any single manual action (like pressing the FX button) should be "slow" enough to allow for doing file operations on the fly. (I understand the basic language constructs - like the handling of strings - is identical with ReaScript(ELL), JSFX, and OSCIIbot.) -Michael Last edited by mschnell; 11-15-2017 at 08:38 AM. |
11-15-2017, 04:28 AM | #27 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
The other thing is that you can't ask Reaper to send you specific data. It's either info about currently selected track/fx or all the info that is defined in the .reaperOSC file. The first option isn't enough, while the second one is too much. You know, LCD can show you two rows of text/data. For example, info about 8 pots, or 8 button, or 8 faders. User can switch between displayed info by pressing dedicated row buttons or touching the needed type of the controller to show the corresponding data. And that type of data should be received from Reaper and stored somewhere, while it's not yet needed, but could be called anytime. |
|
11-15-2017, 06:24 AM | #28 | ||||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
The midi controller can only react to the incoming data momentarily. It doesn't "store" anything. Let's take one FX and it's 64 parameters. What I want is to be able to scroll through their names and values by 8 parameters at the time. When FX is selected in Reaper, Reaper would send all 64 parameters names and values at once. The script will take first 8 and display them at the LCD. The remaining 56 parameters won't be processed or stored. Then, user presses "page down" button to see parameters 9-16. Where do you think they would be received from? Quote:
Quote:
Quote:
What I need is to be able to store all the incoming OSC messages and update that info, when needed. P.S. I feel like I'm repeating myself again and again. This is how memsets are used for the same purpose in MIDIMIX script and, in my opinion, it's one ugly workaround in absence of arrays in EEL2. https://i.imgur.com/V9Ixuk7.png You need to allocate available memory in order to store the needed data in it. You can't just tell oscii-bot to store something. One should specify the needed size of the memory beforehand and base it on the previous allocations. No mistakes are allowed. You can see how the author uses previously reserved space to assign the new one for new variables. Code:
fader_feedback_interrupt_timer = previousValue2+device_faders; memset(fader_feedback_interrupt_timer, time, device_faders); track_volume = fader_feedback_interrupt_timer+device_faders; memset(track_volume, -1, track_bank_size); Last edited by fundorin; 11-15-2017 at 06:52 AM. |
||||
11-15-2017, 08:57 AM | #29 | |||||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
Quote:
Quote:
Quote:
Code:
# Note: FX parameter feedback will only be sent for the track that is currently # selected in the device. If messages exist that can target FX on other tracks, # feedback will be sent whenever the parameter values change. This can be a lot of # data, so only include those messages if you want the feedback. Been there, done that. Quote:
Here's my list of reaperosc files, to assure you that I'm aware of it's capabilities - https://i.imgur.com/kaq2Z0a.png Of cause, I'm using two functions in my script to log all midi and osc data in oscii-bot, though the osc part doesn't want to work, yet. It's been a while since I wrote those oscii-bot scripts. |
|||||
11-15-2017, 09:34 AM | #30 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Fundorin - more encouragement and assorted suggestions to add to Veto's
Comment out as much as possible in the .ReaperOSC file to minimise OSC feedback from Reaper on items the control surface does not need to follow. A lot of the feedback doesn't matter anyway so don't worry about it (except it makes items of interest difficult to pick out in a console window). Just match the parts that matter and do something in the control surface only with those parts. Consider carefully how much "state" will be represented in the device hardware, how much in the OSC control surface (OSCII-bot code) and how much in Reaper and design accordingly. The less state in the control surface the easier the code will be regardless of the programming language and its quirks because the states will get out of step with a human in the loop..... Where will the state or configuration be stored (persist) and restored when the device hardware or Reaper is switched off and back on again? This is a key design decision. One can use memory as pseudo-arrays as your .png screenshot already does. Provided one keeps track of the sizes (i.e the memory offsets) of each item at declaration time and keep (especially write) access within bounds things will work just fine, and every pseudo-array has a name so the code reads OK. This thread might help a bit too https://forum.cockos.com/showthread....ighlight=array with suggestions from Darkstar and others Note that all memset does is set the memory to a value which can be useful only when the programmer already knows that the space has been earmarked. One can instead use a stack to store things in memory too if that data structure fits. One could even use the file system to persist items from memory too: this is how databases work but it's Do It Yourself and probably overkill in the EEL2 / Novation world. |
11-15-2017, 10:07 AM | #31 | |||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
In fact, it might be possible to use strings as a substitute for arrays, dividing useful data in segments with some special symbol or symbols combination, like "Track 1 | Bass | Track 3 | Kick" for string with track names and than parsing that string for the required data. Since strings could be as long as 16kb in length, I think I might implement this method, but using some unique symbols combination, like "d_i_v_i_d_e_r" to separate data in strings. Quote:
Quote:
My current snag is to find a way to store and update data that was already received from Reaper, related to unselected tracks/plugins. Last edited by fundorin; 11-15-2017 at 10:46 AM. Reason: grammar mistakes, as usual |
|||
11-15-2017, 10:57 AM | #32 | ||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
Remember that each bank increment/decrement would make Reaper to send all info about the banks that you're currently scrolling through. Quote:
I took my functions directly from that script by Banned. The thing is that they worked for me a couple of years before, but osc part doesn't work for now. Still need time to figure out, why it isn't working. https://i.imgur.com/SyEFY7Y.png Speaking about Banned. He didn't show up at the forum for two years. A year ago I was googling him because of that and found out his real name, his hometown and FB profile. I was afraid that he might've died. TBH, I still think that he's dead. 😐 |
||
11-15-2017, 02:41 PM | #33 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Thanks for the script. I have no issues with controlling Reaper from the console. What I'm interested in is feedback, so that the info will be updated properly for both LCD and LED buttons.
I think like I need to explain a bit further my concept of mode for the console. Unlike banks, where the same set of controls could be used to control, let's say volume, modes will allow to use the same set for different tasks, like, in mixer mode 8 faders are for controlling track's volume in banks of 8. In, let's say, "second mixer" mode, the same faders would control sends for tracks and in "third mixer) mode they would control receives. Do you understand the concept, Veto? So, when switching between those modes with dedicated buttons, LCD should display corresponding info about the faders. Let's say, the amount of volume in first mode, amount of send in second mode and amount of receive in the third one. For all tracks, divided by the set of 8. Get it? Good. Now, I had no issues with "refresh all surfaces" action, while switching between those mode, while using celphor's version of oscii-bot 0.3. That one second that's needed to update info from Reaper was fine for me. But, imagine, you are in second mode and track which have both sends and receives is selected. You're adjusting all its sends and now you need to adjust its receive. It may not be a typical situation, but, just imagine. So, instead of permanently switching to "Third mixer" mode to get access for receives, you just hold the corresponding button and move first fader, which is now controlling receives, instead of sends. Then, you release the button and continue working with sends. That's the task. The thing is that when the mode is temporarily switched, one needs to see the amount of current receive at the LCD. One needs to wait for a whole second while Reaper refreshed the surface and a little bit more, while the surface itself updates the info on LCD. So, it's all about feedback and not about control or banks or anything else. Most of the info that's sent by Reaper stays the same, and even if it changes, Reaper will send just this info to oscii-bot. I've tried that strings method but yet couldn't get the behaviour. All I could achieve is that the track names were added (concatenated) to the string, alternating with my divider. i couldn't make script to rewrite the names inside the string, yet. Will investigate further tomorrow. Now, about your example: I don't need to store the same type of data in different strings. This way, 1024 strings can come to an end very quickly. I need multi-dimensional arrays with readable names, tbt. P.S. You said that you've met banned in Amsterdam. Do you know his real name? Cause I forgot it and can't remember how I found him. Probably, he had the same nickname at some game account. Last edited by fundorin; 11-15-2017 at 02:47 PM. |
11-15-2017, 03:46 PM | #34 |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
This is the line that I've used:
Code:
@input midi_in MIDI "MIDIIN3 (SL MkII)" @output midi_out MIDI "MIDIOUT3 (SL MkII)" @init @timer @oscmsg @midimsg msg1 == 0xbf ? ( msg2 == 40 && msg3 == 0 ? midisend_str(midi_out,"F000202903031200020002020401090104427574746F6E20320001090304202020310001120104427574746F6E203300011203042020204F4E00F7"); ); |
11-15-2017, 05:15 PM | #35 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
Mixer mode should store arm states, pan, volume, solo, mute by itself, so that any of those states could be displayed on the LCD. Let's leave it for the moment. For now, I have issues with the main function - successfully sending sysex data to the controller. I need @Justin to tell me if I'm doing something wrong or maybe it's oscii-bot's fault and not mine. Those slots in your example aren't constant, so I probably won't use that method to store data. I prefer having a string with understandable name, like reaperTrackNames, that contains names of all tracks. Could you, please, provide me with an example of how to make this string: "oh|hello|world" into this "oh|goodbye|world"? |
|
11-15-2017, 06:02 PM | #36 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Suggest no need to ask Justin (yet). Use MidiOX or a similar midi monitor first to see what's going out to the Novation and even simulate some replies? This will help to see what is happening in Midi and whether the unexpected behaviour is OSCII-bot V0.5, your code, or possibly just to find and reverse engineer errors or differences between the Novation controller and its paper specification. Good luck....
|
11-15-2017, 06:22 PM | #37 | |
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Quote:
It only showed real SYSEX from the controller (switching from Automap mode and back), while sysex from oscii-bot wasn't listed in the monitor. I've also printed that string into log of oscii-bot. Log showed the string as it should, but that's it. I've tried sending the same sysex message many times directly from midi-ox/view/sysex and it worked fine. All the above is with midi-ox. The following is when the same command is sent from oscii-bot (sorry for big size): The code that should clear the LCD. 02 is LCD commands, 02 04 clears LCD. Everything before it is just a universal header for this controller. It lights up some of the transport and other buttons, instead. Depending on the sysex code, more or less buttons will light up: Code:
msg1 == 0xbf ? ( msg2 == 41 && msg3 > 0x00 ? midisend_str(midi_out, "F0 00 20 29 03 03 12 00 02 00 02 02 04 F7"); ); |
|
11-15-2017, 06:50 PM | #38 |
Human being with feelings
Join Date: Feb 2016
Posts: 189
|
Cover the debugging incrementally:-
1. Put a printf statement in (that shows the code block with midisend_str() is reached) 2. Put in midisend() in addition (that shows the code, midi channel and Midi-OX working together as expected for 3 byte midi output) Then 3. Puzzle at the new midisend_str(). But at least the OSCII-bot process hasn't crashed like Celphor |
11-15-2017, 06:55 PM | #39 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 15,758
|
|
11-15-2017, 07:15 PM | #40 | |||
Banned
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
|
Nope. No changes on the LCD. At least, random LEDs stopped to light up.
Sending the same sysex via midi-ox still working. Quote:
Quote:
https://i.imgur.com/kLD0rBz.png Quote:
Last edited by fundorin; 11-15-2017 at 07:24 PM. |
|||
Thread Tools | |
Display Modes | |
|
|