Old 12-09-2017, 01:05 AM   #1
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default General questions

Is it possible to restrict oscii-bot from launching it's new copies, when there's already one copy running? I prefer having it's icon hidden in the tray, so, while constantly switching oscii-bot on and off, I, sometimes, launch a new copy, while the old one is hidden in the tray and can't figure out what's wrong with my script.
"Run minimized" option and other useful options in right click menu for the icon in tray would also be great additions to the future updates.
fundorin is offline   Reply With Quote
Old 12-09-2017, 09:10 AM   #2
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default

One should be able to achieve this (on Windows) by using autohotkey to start OSCII-bot.

autohotkey should be able to either detect a) the pre-existing minimised OSCII-bot window or b) the OSCII-bot process and then, if detected as running, decline to start a new instance of OSCII-bot.
goldenarpharazon is offline   Reply With Quote
Old 12-09-2017, 09:18 AM   #3
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by goldenarpharazon View Post
One should be able to achieve this (on Windows) by using autohotkey to start OSCII-bot.

autohotkey should be able to either detect a) the pre-existing minimised OSCII-bot window or b) the OSCII-bot process and then, if detected as running, decline to start a new instance of OSCII-bot.
Thanks. My question was mainly directed toward devs, tbt.

P.S. What is your name?
fundorin is offline   Reply With Quote
Old 12-11-2017, 10:30 AM   #4
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

In .ReaperOSC file.

FX_PARAM_VALUE r/fxparam/@/value r/fx/@/fxparam/@/value r/track/@/fx/@/fxparam/@/value

Using rotary encoder to change fx parameters with "r/fxparam/%d/value" command.

Sending "-1" and "1" values makes parameter in Reaper jump from far left to far right, respectively.

Sending something, like "-.04" and "0.564" values makes parameter in Reaper move a little bit from the center each time I rotate the encoder. It always jumps back to the center (ROTARY_CENTER is set to 0) at the start of the encoder movement.

Why these Reaper does not take fractional values to move parameter gradually, depending of the value sign/encoder direction?
fundorin is offline   Reply With Quote
Old 12-11-2017, 10:48 AM   #5
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

I never saw that a Rotary sends increments, but usually rotaries have an LED Ring showing the would-be value and hence the device does know (and for displaying it needs to know) the absolute value.

OTOH, AFAIK, the "standard" in OSC is to encode parameter changes as 0.0 ... 1.0 in floating point as a representation of the absolute parameter value min ... max.

Obviously in your example "1" is "1.0" and results in maximum and "-1" is clamped to "0.0" and results in minimum. Wich seems rather correct to me.

I suppose you need to do an "OSC-dialogue" and first fetch the current value (to be displayed on the LED Ring, if exists) and then send the value esulting from the increment.

-Michael
mschnell is online now   Reply With Quote
Old 12-11-2017, 02:06 PM   #6
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by mschnell View Post
I never saw that a Rotary sends increments, but usually rotaries have an LED Ring showing the would-be value and hence the device does know (and for displaying it needs to know) the absolute value.
From reaperOSC file:
Code:
r: rotary. The device triggers the action in the forward direction when sent  
# with an argument greater than ROTARY_CENTER, and in the reverse direction when 
# sent with an argument less than ROTARY_CENTER. For some messages, the magnitude 
# of the argument affects the rate of change.
This is what I'm interested in.

There are also this commands available in ReaperOSC, but they would only work with actions (numerical or strings, in case of SWS actions) and not with ReaperOSC commands, like "r/track/volume".

Code:
ACTION_SOFT f/action/@/cc/soft
ACTION_RELATIVE f/action/@/cc/relative
Quote:
Originally Posted by mschnell View Post

OTOH, AFAIK, the "standard" in OSC is to encode parameter changes as 0.0 ... 1.0 in floating point as a representation of the absolute parameter value min ... max.
True, but that's not the point here. Soft/Relative/Absolute mode are available for midi learn and for regular actions, but not for ReaperOSC native commands.

Quote:
Originally Posted by mschnell View Post
Obviously in your example "1" is "1.0" and results in maximum and "-1" is clamped to "0.0" and results in minimum. Wich seems rather correct to me.
You don't understand. Yes, it's always 1-0 with OSC. The thing is how Reaper interprets those values. Again, Soft/Relative/Absolute modes.


Quote:
Originally Posted by mschnell View Post
I suppose you need to do an "OSC-dialogue" and first fetch the current value (to be displayed on the LED Ring, if exists) and then send the value esulting from the increment.
This is not what I need. I'm not talking about feedback right now. Making LED rings to reflect values from Reaper is the easiest thing. It's all about smooth controlling the parameters.
Also, It seems like Reaper doesn't send FX parameter names/values to the device for me. Both with default and some third-party ReaperOSC files.
I suppose, one should send Reaper some additional command to notify it that the device is in FX control mode now.
fundorin is offline   Reply With Quote
Old 12-11-2017, 02:18 PM   #7
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Interesting stuff indeed !

As I did not try to use the Reaper OSC interface (with OCSII-Bot I on the contrary communicate with Reaper via Midi and with a hardware Mixer via OSC), I can't comment on that.

While 0.0....1.0 is "standard" with OSC, AFAIK, it's perfectly viable to use the protocol for any kind of values and with any way to interpret them as the sender and receiver agree upon.

-Michael

Last edited by mschnell; 12-31-2017 at 12:07 AM.
mschnell is online now   Reply With Quote
Old 12-30-2017, 09:55 PM   #8
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default multiple track selection

DEVICE_TRACK_SELECT i/device/track/select t/device/track/select/@

This command selects each track from the bank exclusively, deselecting all other already selected tracks, when the corresponding button on the device is pressed.
I'm fine with it, but also want to have an ability to select multiple tracks at once from the surface with a different set of buttons.

How should it be done properly? What command should I use.

Tried both i/device/track/select and t/device/track/select/.
Even added DEVICE_TRACK_SELECT b/device/track/select/@ line to the config file.
All these options are selecting track from the bank exclusively, deselecting all other tracks in the project.
fundorin is offline   Reply With Quote
Old 01-02-2018, 10:26 AM   #9
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default Multiple track selection - reply

This code will select multiple tracks in a bank

Code:
oscsend(OSC_to_REAPER, "t/track/1,2,3,4,5,6,7,8/select/toggle", 1); 	// select all tracks in currently selected bank  (reselects tracks after mixer use)
See this code in context in the AKAI MIDIMIX control surface and in Banned's Peavey StudioMix. AFAIK for a given or imagined OSC string pattern it's only experimentation that will determine whether a toggle is implemented or whether multiple parameters are allowed.
goldenarpharazon is offline   Reply With Quote
Old 01-02-2018, 11:54 AM   #10
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Thanks, but I don't think that this solution would be helpful for the situation, when Track 1 (in Reaper) is already selected and one needs to also select Track 16 (in Reaper).
So, we switch to bank 2 on the device and, then, when selecting tracks "1,8", device will select tracks 9 and 16 and deselect Track 1 in Reaper.
Some other option needed.

It may somehow be solved by performing series of custom actions, like,

1. "Script: me2beats_Save selected tracks, slot 1.lua"
3. "oscsend(OSC_to_REAPER, "t/track/@select/toggle");
3. "Script: me2beats_Restore selected tracks, slot 1 (add to selection).lua"

but this isn't a universal solution, since custom actions doesn't have persistent action IDs in Reaper.
fundorin is offline   Reply With Quote
Old 01-02-2018, 12:50 PM   #11
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default

If the track selections are to be wider than a bank, then try using the native Reaper actions "Track: Select Track nn"

This post may help too if there is some Reaper display or UI change also expected on doing the track selection
https://forum.cockos.com/showthread.php?t=171832
goldenarpharazon is offline   Reply With Quote
Old 01-02-2018, 01:06 PM   #12
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by goldenarpharazon View Post
If the track selections are to be wider than a bank, then try using the native Reaper actions "Track: Select Track nn"
Since Reaper doesn't send current selected bank number to the device, it's not possible to simply multiply device track number by current bank number to reach the needed track. And, in case of device_bank_follows last_touched (I use this option), Reaper bank could start from any track in the project.

Selecting tracks by 1-99 actions isn't possible by the same reason. Let's say, I've clicked track 5 in Reaper. Then, the current bank would be tracks 5-12 for buttons 1-8 on the device. So, what action should be performed when I'd press button 3? Ideally, the device should send "select track 7 (keeping selection)". We can identify the bank position by using "last touched track" feedback from Reaper.
Now, let's try to select track 3 in Reaper, while track 5 is still selected. We press "bank-" button on the device. Now, the bank includes tracks 1-8 for buttons 1-8 and "last touched track" is still 5, which would mess the selection, if we would want to use "last touched" as an anchor point for direct selection action in Reaper. The script would still think that button 3 is mapped to the track 7, while we need it to select track 3.

I hope, you can follow my logic here. In short:
1. Using "last selected track" for direct selecting tracks isn't an option (there could be more than one that is already selected).
2. Device never knows what bank was selected.
fundorin is offline   Reply With Quote
Old 01-03-2018, 07:41 AM   #13
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default

The problem starts to make some sense at a detailed level but without an obvious Reaper action or an OSC related "bullet" as the solution.

Might it not help to take a step back from the details and think at an abstracted design level about the design principles and the compromise(s) in user experience and implementation associated with them? Here are some suggestions
  • From the eyes and hands of the DAW user, is Reaper in charge of the hardware device or is the hardware device in charge of Reaper?
  • To achieve the desired usability how much "state" needs to be stored in the hardware device, in the control surface code, and in Reaper itself? The design goal should be to minimise state tracking since it is likely an undesirable source of code complexity, system errors, and user confusion.
  • How can or might the desired user functionality be done given the different behaviour inherent (or accidental) with the various .ReaperOSC "device follows" type options?
goldenarpharazon is offline   Reply With Quote
Old 01-03-2018, 10:12 AM   #14
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Quote:
Originally Posted by fundorin View Post
2. Device never knows what bank was selected.
Shouldn't it query such state to get in sync ?

-Michael
mschnell is online now   Reply With Quote
Old 01-03-2018, 04:49 PM   #15
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

There's no way to do so. Reaper never sends that information.
fundorin is offline   Reply With Quote
Old 01-04-2018, 07:52 AM   #16
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default

Quote:
Originally Posted by fundorin View Post
There's no way to do so. Reaper never sends that information.
That answer forces the design principle then:

If Reaper does not and will not give sufficient feedback on track or bank selection via OSC on a change, or on a "refresh all control surfaces" action then the Novation and the OSC control surface will have to be in charge of, and keep a record of, the track & bank selection state.

Then just add to this decision the means of bringing back to a consistent state if the human changes things at the Reaper end or the imaginary state tracking information handshake goes wrong for another technical reason. Use the DAW operating human if needs as the simplest way to manually get back or keep in sync.

Quote:
Originally Posted by fundorin View Post
Since Reaper doesn't send current selected bank number to the device, it's not possible to simply multiply device track number by current bank number to reach the needed track.
If it can help, then in the MIDIMIX control surface when banking, an OSC string is sent for first track number in the bank when a "bank left" or a "bank right" occurs. This track number can be detected and calculated and used in the control surface code.

Last edited by goldenarpharazon; 01-04-2018 at 11:34 AM. Reason: Extra help added
goldenarpharazon is offline   Reply With Quote
Old 01-04-2018, 12:35 PM   #17
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by goldenarpharazon View Post
That answer forces the design principle then:

If Reaper does not and will not give sufficient feedback on track or bank selection via OSC on a change, or on a "refresh all control surfaces" action then the Novation and the OSC control surface will have to be in charge of, and keep a record of, the track & bank selection state.
That's a double-edged sword. First, setting "track_banks_follows device" will disable mixer view scrolling to selected tracks in Reaper. Second, It won't be possible to quickly move the console's view to the selected (with mouse) track in Reaper.

I've tried calculating banks on the surface side. To many flows with this decision. Not worth it.
fundorin is offline   Reply With Quote
Old 01-08-2018, 10:47 AM   #18
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Why float assignments are working properly with this code, but not the strings? What is a proper way to write string values into the memset?





All I get now is empty values:
fundorin is offline   Reply With Quote
Old 01-08-2018, 01:48 PM   #19
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Quote:
Originally Posted by fundorin View Post
What is a proper way to write string values into the memset?
I do understand that you decline to accept this, but in EEL you don't write strings in memsets. There is a dedicated "StringSet".

It is possible to write (I seem to remember) up to 5 Bytes from a string into an element of an array ("memset"). But why should you want to do that ?

-Michael

Last edited by mschnell; 01-08-2018 at 10:29 PM.
mschnell is online now   Reply With Quote
Old 01-08-2018, 02:32 PM   #20
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

I don't decline memsets (i dislike address assigning and related issues, like the current one, to be exact), but there's no other option.
The thing is that, for some reason, mem_set_values doesn't work, either.




There's either no value at all, or the same value is duplicated for all variables.
fundorin is offline   Reply With Quote
Old 01-08-2018, 02:43 PM   #21
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Here's a simpler example.


Output upon corresponding osc incoming message:


.ReaperOSC entry with 'string' type for this action:

Last edited by fundorin; 01-08-2018 at 02:52 PM.
fundorin is offline   Reply With Quote
Old 01-08-2018, 03:02 PM   #22
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

This code prints volume values for all tracks, while it should always display "Track 1" volume as in oscSelTrackVolStr[1]:


Output:


UPD. This doesn't work:


I'm going slightly mad.

Last edited by fundorin; 01-08-2018 at 03:07 PM.
fundorin is offline   Reply With Quote
Old 01-08-2018, 03:12 PM   #23
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

This is getting out of hand!


fundorin is offline   Reply With Quote
Old 01-08-2018, 03:39 PM   #24
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,716
Default

I can't see all of your code, but I think the problem your having is because of the way strings work in EEL. Strings are a bit of a second-class citizen in EEL -- variables which reference them are actually numbers which point to the string buffer.

oscSelTrackVolStr[0] through oscSelTrackVolStr[n] need to be initialized to point to distinct strings. You could do this by setting:
Code:
oscSelTrackVolStr[0] = #;
oscSelTrackVolStr[1] = #;
oscSelTrackVolStr[2] = #;
or
Code:
mem_set_values(oscSelTrackVolStr, #,#,#); // or any more # as you need
(those two syntaxes are nearly identical in function).

Which would allocate an anonymous string buffer for each, but that limit is still constant.

If you want to do it purely programmatically, you could assign the pointers to the values 0..1023 which are the user strings that you can use.
Code:
i = 0;
loop(3, 
  oscSelTrackVolStr[i] = i; i += 1; 
);
using an array in this case is actually redundant, you could just use:

Code:
oscSelTrackVolStr = 0;
...
oscparm(0,'s', oscSelTrackVolStr+trackNumber); // for track number 1, use global string index 1, track number 2 use string index 2, etc.
printf("Track Number: %d Value: %s\n",trackNumber,oscSelTrackVolStr+trackNumber);
Finally, I should mention that if possible, it's probably a good idea to avoid keeping string copies of things. E.g. if you have a string which represents a volume, convert it to a number, store that, and convert back to a string on demand.

P.S. if you want to debug what a string points to, you can use something like:
Code:
v="some string";
printf("string: %d='%s'\n", v,v);
v = #str;
printf("string: %d='%s'\n", v,v);
Justin is offline   Reply With Quote
Old 01-08-2018, 04:11 PM   #25
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

First of all, I would like to thank you for coming here. There's literally no one one interested in OSC or osscii-bot, except, maybe, Michael and goldenpharazon. And my related questions are almost always left unanswered.

Quote:
Originally Posted by Justin View Post


Code:
oscSelTrackVolStr = 0;
...
oscparm(0,'s', oscSelTrackVolStr+trackNumber); // for track number 1, use global string index 1, track number 2 use string index 2, etc.
printf("Track Number: %d Value: %s\n",trackNumber,oscSelTrackVolStr+trackNumber);
This one seems to works. I'll use it. Thanks a lot!

Quote:
Originally Posted by Justin View Post
Finally, I should mention that if possible, it's probably a good idea to avoid keeping string copies of things. E.g. if you have a string which represents a volume, convert it to a number, store that, and convert back to a string on demand.
The thing is that I started implementing LCD feedback into my script and the first task was to display track names (fx names), not numbers. Volume strings are used here mostly as an example, since it's faster to adjust volume fader to check for changes, instead of renaming tracks.

Quote:
Originally Posted by Justin View Post
P.S. if you want to debug what a string points to, you can use something like:
Code:
v="some string";
printf("string: %d='%s'\n", v,v);
v = #str;
printf("string: %d='%s'\n", v,v);
This would also be useful.

I have a question about MIDIACTION and MIDILISTACTION. What is their purpose? Is it possible to use them in relative/absolute modes?
If I want to control "Adjust solo in front dim (MIDI CC/mousewheel only)" (action 987) with an encoder/pot via OSC, what command should I send to Reaper and what should be sent as an argument to this command?
Related thread: https://forum.cockos.com/showthread.php?t=201649

I've made a post last year about "learn" action, which is only working, when called via midi command, hotkey or from the action list, but not when it was assigned to the osc command.
Thread with demonstration: https://forum.cockos.com/showthread.php?t=200551

I'm also wondering of, how to assign encoder to the internal .ReaperOSC actions, like "n/track/volume", considering that encoder sends +1/+65 when turned CW/CCW and there's no appropriate settings in .ReaperOSC.
The same is true for assigning OSC commands to actions in the action list. "CC mode" button becomes disabled, and there's no similar button for osc, where it would be possible to set control type, like relative/absolute/etc.
Loosely related thread here: https://forum.cockos.com/showthread.php?t=200631

Is it possible for you to check those questions and answer in those threads or just here? Thanks in advance.
fundorin is offline   Reply With Quote
Old 01-08-2018, 10:35 PM   #26
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Quote:
Originally Posted by fundorin View Post
my related questions are almost always left unanswered.
Not true. I answered to close to all your questions, but seemingly you don't understand my wording - or decline to try to make sense of what I am saying, or I don't succeed in understanding what exactly you are asking. Obviously, regarding technology, we are talking in completely different languages. (And you did not really try to thorroughly understand / check out what the (OK: rather sparse) OSCII-Bot / EEL documentation says.)

Quote:
Originally Posted by fundorin View Post
This would also be useful.
This obvious code snipped was the first I did when checking out how strings work in EEL, at the point I needed strings for my OSCII-Bot script.

-Michael, getting tired of this and wishing Justin more luck on that behalf.

Last edited by mschnell; 01-08-2018 at 10:49 PM.
mschnell is online now   Reply With Quote
Old 01-09-2018, 01:36 AM   #27
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

The thing is that I either can't understand what you're proposing, due lack of my programming skills, or I can't properly describe my issue, to get useful answer about it. Anyway, it's all about me and not you.

-Not Michael

Last edited by fundorin; 01-09-2018 at 06:11 AM.
fundorin is offline   Reply With Quote
Old 01-09-2018, 05:25 AM   #28
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Code:
    position = 11;
    pos = sprintf(str_out, "\\x%02X", position);
    pos2 = "\x11";
    
    printf("    pos - %s\n", pos);
    printf("   pos2 - %s\n", pos2);
    printf("strpos2 - %s\n", hex2str(pos2));
output:



Why pos is a text string, while pos2 is hex? What should be done to store pos value as hex?

P.S. I've created a thread, asking how to properly convert dec numbers into hex numbers, but then I thought that the I've solved the issue and deleted that thread. Turns out, that I still need to find a way of how to convert those numbers in EEL2.
In Lua and JS it's alao possible to convert digits with tostring(10) or tostring(16). Yet, I don't understand how to make constructed string value to behave like hex value in EEL2

Last edited by fundorin; 01-09-2018 at 06:10 AM.
fundorin is offline   Reply With Quote
Old 01-09-2018, 06:32 AM   #29
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Quote:
Originally Posted by fundorin View Post
Yet, I don't understand how to make constructed string value to behave like hex value in EEL2
I don't suppose anybody can understand what you are asking.

First you need to define what exactly you mean by "string value", and by "hex value" and by "behave like".

e.g.:

"string value" is a string that contains decimal digits that might be able to be interpreted as an integer number.

"hex value" is a string that contains decimal digits and letters A..F that might be able to be interpreted as an integer number.

"behave like" ????


-Michael
mschnell is online now   Reply With Quote
Old 01-09-2018, 06:55 AM   #30
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

// HEX string. When printed to log as string, won't show anything, until converted into string with a special function, which was written by Justin. Then, log will display "0B".
pos = "\x11";


//Regular string. When printed, will display "\x0B" in log.
position = 11;
pos2 = sprintf(#, "\\x%2X", position);

printf("%s", pos); // []
printf("%s", pos2); // \x0B
printf("%s", hex2str(pos)); // 0B

So, we have two variables, pos and pos2, containing the same value - "\x0B". The thing is that pos is determined as hex and pos2 as a string.
The question is, how to make pos2 value type as hex.
fundorin is offline   Reply With Quote
Old 01-09-2018, 08:28 AM   #31
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Still can't figure this out.

So, the task is:
Construct SYSEX message with various small parts, so it wouold be possible to display data from Reaper on the LCD:

constants:
Code:
lcdSysexHeader    = "\xF0\x00\x20\x29\x03\x03\x12\x00\x02\x00\x02";    // LCD HEADER
lcdSetCursor    = "\x01";  // command to position cursor
lcdLTLine        = "\x01";  // top line on the left LCD
lcdTextStart    = "\x04";  // begin text part
lcdTextEnd        = "\x00"; // finish text part
lcdSysexEnd        = "\xF7";                                            // LCD END
constructor:
Code:
strcat(lcdTrackName,sprintf(#,"%s%s%s%s%s%s%s%s",lcdSysexHeader,lcdSetCursor,position,lcdLTLine,lcdTextStart,str2hex(sysexInput),lcdTextEnd, lcdSysexEnd));
For now, two parts of the message may vary:
1. str2hex(sysexInput) where sysexInput is a currently selected track's name in string format. This one is working fine. using my custom string to hex conversion function.
2. position - cursor position on the LCD. Doesn't work, for now.
If position will be replaced by "\x00", for example, the cursor will be set to the first symbol position at the top line of the screen. "\x01" for the second position and so on.

What I need is to substitute "\x00" here with a variable\function, that would take decimal integer number as an input and convert it to hexadecimal number string, since "\x**" type of strings are used in oscii-bot. For example, 1 bill become "\x01", 11 will be converted into "\x0B".

When I'm trying to construct sysex string with
pos = sprintf(#, "\\x%X", position));
or some other methods, they don't work. pos value is always a text string, while I need it to be "hex string", like those constants above.
fundorin is offline   Reply With Quote
Old 01-09-2018, 02:45 PM   #32
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Quote:
Originally Posted by fundorin View Post
So, we have two variables, pos and pos2, containing the same value - "\x0B".
Please try to use exact wording.

e.g: -> we have two variables, pos and pos2 each holding the id of a string. Both these strings contain the character sequence "\x0B".
That obviously is not true.

Regarding your "print" commands, correct is:

->
we have a variable pos that holds the number 11.
we have a variable pos2 that holds the index of a string. This strings contain the character sequence "\x0B".

No idea what happens to your x11 which would be 17. What exactly did you intend to do by pos = "\x11" ? There is no clear definition in the OSCII-Bot code reference, but it seems that it should create a string that contains a single character with value 17 (hence not printable) and set the variable pos to the value of the index of this string. (I did not check this right now.)


-Michael

Last edited by mschnell; 01-09-2018 at 10:29 PM.
mschnell is online now   Reply With Quote
Old 01-09-2018, 07:03 PM   #33
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default

Quote:
Originally Posted by fundorin View Post
I have a question about MIDIACTION and MIDILISTACTION. What is their purpose? Is it possible to use them in relative/absolute modes?
If I want to control "Adjust solo in front dim (MIDI CC/mousewheel only)" (action 987) with an encoder/pot via OSC, what command should I send to Reaper and what should be sent as an argument to this command?
Related thread: https://forum.cockos.com/showthread.php?t=201649

Is it possible for you to check those questions and answer in those threads or just here? Thanks in advance.
Answer provided for MIDIACTION and how to call action 987 in the thread https://forum.cockos.com/showthread.php?t=201649

With regard to how to compose binary strings that are suitable for sending via SYSEX the key hints needed to the two key functions for accessing binary [byte] strings i.e. str_getchar() and str_setchar() were in Justin's original release post and advice that followed shortly afterwards. See https://forum.cockos.com/showpost.ph...0&postcount=17 again.

Using a suitable midi monitor is probably the best and sole debug means of seeing if the binary [byte] string has been constructed correctly and then output.

If one switches between midi monitor output and what is output by printf() then the understanding and learning may be more complicated 1. because of the internal representation of strings in EEL (that Justin has tried to explain) and 2. Because of the format translation that can be done in printf() on output. The output of the (hoped for) SYSEX binary [byte] string will likely different in the midi monitor and the printf().

If one uses other string functions on binary [byte] strings without developing a good understanding of the EEL internal data representation then, as found in the posts asking for help, the results may quite likely be unpredictable or not wanted.

One could use that midi monitor binary [byte] string output as a constant source of truth if one is trying to reverse engineer or visualise the internal representation of strings in EEL/OSCII-bot

Do keep trying using logical problem solving steps on simple example problems. Simple example problems are easier to learn and easier to explain or present on the forum when asking for help. And well done and thanks to Michael for helping too. Good luck.
goldenarpharazon is offline   Reply With Quote
Old 01-09-2018, 07:46 PM   #34
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

I suppose that getchar/setchar isn't appropriate here, cause character "9"
would be "39" in hex", while "9" in hex" is a "horizontal tab".


That's how Justin's str2hex function works, picking character by character, converting them in hex and putting into the new string.
This function works fine for displaying data on the screen as characters, but not for direct numbers conversion like this:
fundorin is offline   Reply With Quote
Old 01-10-2018, 01:05 AM   #35
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by mschnell View Post
we have a variable pos that holds the number 11.
Not true. According to the reference, hex numbers should be assigned as $x** or 0x**, without using the quotation marks.
Like var = $xBF



pos = "\x11"; is a string and it's a string that is used in oscii-bot to send sysex data to the controller. The function's name itself suggests it: midisend_str

And the issue is that when a string is set explicitly, it's recognized by oscii-bot as a hex number, but when it's constructed with
strcat(pos, sprintf(#, "\\x%X", position));
it's, suddenly, a text string.

At the very same time, this code
strcat(lcdTrackName,sprintf(#,"%s%s%s%s%s%s%s%s",l cdSysexHeader,lcdSetCursor,"\x00",lcdRTLine,lcdTex tStart,str2hex(sysexInput),lcdTextEnd, lcdSysexEnd));
is also a string, but it's a proper sysex message. This is what I can't understand.

Even "%s%s%s%s%s%s%s%s" in the code line above suggests that "\x01" in lcdSetCursor = "\x01"; and any other part of the message is a string and not a hex number.

P.S. I feel that dec numbe should be converted into hex number and the result is put into a string. The question is, how to the conversion in EEL2.

Last edited by fundorin; 01-10-2018 at 01:56 AM.
fundorin is offline   Reply With Quote
Old 01-10-2018, 02:11 AM   #36
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

str_getchar might be a solution. Need a bit more time for experiments.

UPD. Seems like it's not.

Last edited by fundorin; 01-10-2018 at 02:59 AM.
fundorin is offline   Reply With Quote
Old 01-10-2018, 06:01 AM   #37
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default Guidance on EEL strings and characters

Fundorin. Take a step back from the code that is now becoming a bit frustrating and try and think about what is happening with characters and strings and their representation within EEL and in the computer itself.

Piece this thinking together one step at time.

There are a number of separate but related key topics as follows, which if understood better leads to the "answer", and when, or if any character or string "conversion" is taking, or needs to take place.

The (loosely called) character might appear

- As a 7 bit value in a SYSEX byte

- As a series of bytes concatenated together that make a SYSEX byte stream (that could be called a "byte string")

-As a character value stored in an EEL string
-- How that value is stored in EEL
-- What that value is intended to represent internally in EEL, or mean or become externally
Note that all the string functions in OSCII-bot take place on these string values not characters.
Using "Unsigned chars" in str_getchar() will be the safest way to explicitly read or write the whole 8 bits of the desired character in a string.

Influencing this EEL string storage there are the OSCII-bot variables that are really designed to store a 64bit double precision real number but they are also adapted for characters and strings by pointing to a string buffer.

- As a character, string, hex or octal representation in an external output stream (which could be to a GUI console, terminal, printer or file output) or at compile time when coded representations and escape characters are converted into internal storage values. These representations are what is shown in the example white tables in post #34. These are not the same as the internal representations although they are related by a chosen or inbuilt input or output conversion.

To manipulate characters for SYSEX one needs to understand 7 bit ASCII characters and the difference between printable and non printable characters. There is a lot of tutorial material on the nature of characters for the C programming language but take care in that C strings are rather different to EEL strings.

Hope that helps a bit and gives the correct computer/EEL terminology in which to ask more detailed or specific questions.
goldenarpharazon is offline   Reply With Quote
Old 01-10-2018, 06:02 AM   #38
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,636
Default

Quote:
Originally Posted by fundorin View Post
Not true.
You wrote:

printf("%s", hex2str(pos)); // 0B

This shows that at this point in the program the value in pos is 11 (aka 0B hex).

I can't comment on how that value has been assigned to pos.

-Michael
mschnell is online now   Reply With Quote
Old 01-10-2018, 06:19 AM   #39
fundorin
Banned
 
Join Date: Feb 2014
Location: Moscow, Russia
Posts: 554
Default

Quote:
Originally Posted by goldenarpharazon View Post
To manipulate characters for SYSEX one needs to understand 7 bit ASCII characters and the difference between printable and non printable characters. There is a lot of tutorial material on the nature of characters for the C programming language but take care in that C strings are rather different to EEL strings.
Thank you for trying to help. This is what I don't get.

Let's take a simple example (variable position has int 11 value):
Code:
    num1 = sprintf(#,"\\x%02X", position);
    num2 = sprintf(#, "%s", num1);
    num3 = "\x0B";

    printf("position - %d\n", position);
    printf("num1 - %s\n", num1);
    printf("num2 - %s\n", num2);
    printf("num3 - %s\n", num3);
    printf("cnv3 - %s\n", hex2str(num3));
output:


We have dec int position with value 11. Printed as double.
We write position into num1 in hex format as a string, adding "\x" in front and making it two characters, minimum. Printed as a string.
We write num1 into num2 in string format as a string. Printed as a string.
We assign "\x0B" text string as a value to num3. Cannot be printed as a string. Why?!
If we convert it into string with a function, then it can be printed as a string.
How come that direct assignment makes that "\x0B" string a hex value for oscii-bot?

P.S. Conversion function:
Code:
function hex2str(str_in) local(str_out, pos, len) (            // Formatting HEX values to strings 
    strcpy(str_out=#,""); 
    len=strlen(str_in);
    pos=0;
    while (pos<len) (
        strcat(str_out,sprintf(#,"%02X ",str_getchar(str_in,pos)));
        pos+=1;
        );
      str_setlen(str_out,strlen(str_out)-1); // returns str_out
    );
fundorin is offline   Reply With Quote
Old 01-10-2018, 07:56 AM   #40
goldenarpharazon
Human being with feelings
 
Join Date: Feb 2016
Posts: 189
Default

Quote:
Originally Posted by fundorin View Post
We assign "\x0B" text string as a value to num3. Cannot be printed as a string. [B]Why?!
That example is now part of clear code written for learning and testing purposes. Makes it easier to hazard an answer. Thanks.

This is probably because rather than string, "\x0B" is turned by the compiler into a single character because \x is an escape character so the executed code will end up with the single character byte for hex 0B, which is a non printable character (a vertical tab) when printf()ed with %s or other format conversion.

If one uses "\\x0B" instead, then it has an \ escape character to escape the escape character \ followed by x so probably produces the string expected.

Information about escape characters in C strings explains this. It's an example of a nasty kind of bug where a single character (in this case omitted) compiles without error but has completely changed the programmer's intention.

Last edited by goldenarpharazon; 01-10-2018 at 12:48 PM. Reason: Better explanation with solution
goldenarpharazon 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 01:09 AM.


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