Old 07-02-2022, 07:53 PM   #1
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default String to Hex

Hi.
I'm testing OSC output from TouchOSC and hoping to convert OSC to Midi to send to my DAW. TouchOSC can send Midi directly but I'm just testing using it for now.
I'm able to capture an OSC message and multiple parameters. In all my tests, OSCii-bot will only receive OSC parameters that are strings. I can send out an Integer or Float of course but OSCii-bot will not read it.

I created a Fader for testing in TouchOSC called "/Note" with 2 string parameters. The 1st parameter outputs "60" to represent the Middle C note. The 2nd parameter outputs the fader level to represent Velocity from 0-127.

I'm able to log the OSC message using the following code:
Code:
oscmatch("/Note",$'s') ? (
	  oscparm(idx,type);
	  type=='s' ? (
		    #note = null; #volume = null; //must use #variables
		
		    oscparm(0,'s',#note);
		    oscparm(1,'s',#volume); 

		    printf(oscstr);
		    printf (" Note: ");
		    printf (#note);
		    printf (" Volume: ");
		    printf(#volume);
	  );
);
How can I convert the string output to Hex in order to create my msg1, msg2 and msg3 needed to output Midi? I have researched this forum and don't see the solution to this seemingly obvious question. FYI, you can probably tell I'm not a programmer. Just trying to get by using the examples I see. This took me a very long time to cobble together the code above ha ha.
Thank you.

Last edited by procedure; 07-07-2022 at 09:45 AM.
procedure is offline   Reply With Quote
Old 07-05-2022, 06:12 PM   #2
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Is my question off-the-wall somehow or the answer so obvious...

In the C language, I do now see people creating their own functions to convert an integer into a Hex value. So I think that can be handled similarly.

I see the C language has functions that could help convert a string to a integer but I don't see that in EEL2. Can that be done? Doesn't everyone need to convert a string to Hex in order to send out Midi?
procedure is offline   Reply With Quote
Old 07-06-2022, 04:30 AM   #3
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

If I understand correctly, you're getting 0-127 in string format but the output format needs to be a number.

In this case try this:

Code:
match("%i",#input_value,output_value);
"%i" : output format, integer
#input : input string containing your OSC value
output_value : variable that gets to store the value for MIDI output
Fleeesch is offline   Reply With Quote
Old 07-06-2022, 12:04 PM   #4
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Thanks very much for responding.
Here is the current version of my code with your code added at the end:
Code:
oscmatch("/NoteOn/",$'s') ? (
	oscparm(idx,type);
	type=='s' ? (
		#note = null; #velocity = null;
		
		oscparm(0,'s',#note);
		oscparm(1,'s',#velocity); 

		printf(oscstr);
		printf (" Note: ");
		printf (#note);
		printf (" Velocity: ");
		printf(#velocity);
		printf("\n");
		
		match("%i",#note,intNote);
		printf("this is intNote: ");
		printf(intNote);
		printf("\n");

		match("%i",#velocity,intVelocity);
		printf("this is intVelocity: ");
		printf(intVelocity);
		printf("\n");
	);
);
The OSCII-bot LOG window gets this when I move a fader two times in TouchOSC:

/NoteOn/ Note: 60 Velocity: 95.19064
this is intNote:
this is intVelocity:
/NoteOn/ Note: 60 Velocity: 35.404
this is intNote:
this is intVelocity:

So I'm not able to get a conversion with either OSC argument. I tried it with #intNote and #intVelocity as well. I don't really understand the use of the types of variables from the programming guide. Any ideas?
Thanks.

Last edited by procedure; 07-07-2022 at 09:45 AM.
procedure is offline   Reply With Quote
Old 07-06-2022, 01:27 PM   #5
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

Following the programming manual printf() does what sprintf() does, it's a function used to convert numbers to strings. If you just put a number into it there should be some kind of an error message.

sprintf goes like
Code:
sprintf(#string_out,"%i",input_value)
From right to left: input_value goes in, gets formatted as an integer, string goes out.

For sending MIDI you use this one:

midisend(device_index,m1,m2,m3)

Sends a simple 3 byte message. device_index is the index number of the midi device, m1 the status byte (type of message + channel), m2 the controller number, m3 the value.

So you wanna do something like sending modwheel on channel 1, max position to the first midi device in the list you can do this:

Code:
midisend(0,176,1,127);

or in hex

midisend(0,0xB0,0x01,0x7F);

same thing, just different appearance.
This table here is a good overview of MIDI messages.
Comes with all the data formats and whatnot.

Maybe I'll come up with a quick solution and leave some code that should allow you to write a simple OSC-MIDI converter. Would be in my interest, too, could use some scripts here and there. OscII Bot just won't output any gfx on my machines, sample scripts ain't working right, don't know why, have to go figure.
Fleeesch is offline   Reply With Quote
Old 07-06-2022, 04:26 PM   #6
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Thank you very much.
So this is great I now get 2 arguments that are integers from the following code. (This code is completely ridiculous since I'm converting back and forth from floats and strings and integers over and over but I don't know another way...)

Now I just need to convert integers to HEX. You are a hero if you can code that. That would be amazing Thank you.

---------------------
Code:
oscmatch("/NoteOn/",$'s') ? (
  oscparm(idx,type);
  type=='s' ? (
    #note = null; #velocity = null;//must use #variables

    oscparm(0,'s',#note); //string
    oscparm(1,'s',#velocity); //string

    printf(oscstr);
    printf (" Note: ");
    printf (#note);
    printf (" Velocity: ");
    printf(#velocity);
    printf("\n");

    //OSC Arg 1 - note
    match("%i",#note,intNote); //convert string to integer
    sprintf(#string_out1,"%i",intNote); //convert int to string again! printf only prints strings
    printf("this is intNote: ");
    printf(#string_out1);
    printf("\n");

    //OSC Arg 2 - velocity
    match("%f",#velocity,floatVelocity);//convert string to float
    floatVelocity = floor(floatVelocity);//round float to nearest decimal (will be #.00000)
    sprintf(#strVelocity,"%i",floatVelocity);//converts float to string (but will look like integer without #.00000)
    match("%i",#strVelocity,intVelocity);//convert string to integer
    sprintf(#string_out2,"%i",intVelocity); //convert int to string again! printf only prints strings
    printf("this is intVelocity: ");
    printf(#string_out2);
    printf("\n");
  );
);
--------------------------
And the LOG reads:
Code:
/NoteOn/ Note: 60 Velocity: 48.527893
this is intNote: 60
this is intVelocity: 48

Last edited by procedure; 07-07-2022 at 09:48 AM.
procedure is offline   Reply With Quote
Old 07-07-2022, 11:47 AM   #7
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

Sorry, didn't have much time today. Read a little bit into OSCii Bot, eventually I'll find the time to leave a code snippet behind.

You don't happen to use Reaper as your DAW? Because that would make things a little bit easier. You could get yourself the free plugin 'ReaLearn', which has OSC to "control stuff in your DAW" conversion built into it.
Fleeesch is offline   Reply With Quote
Old 07-07-2022, 12:00 PM   #8
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

I personally don't use Reaper. But I want to make a Unity VR app that sends OSC & midi to any DAW. I'm in the testing phase now.
Thanks for hanging in there.
procedure is offline   Reply With Quote
Old 07-07-2022, 01:24 PM   #9
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

I did some trial and error using my old version of TouchOSC. Take a look:

Quote:
// this one here gets stuff from touch osc and sends it to a virtual midi port

// receive every osc message coming from port 8000
@input osc_in OSC "*:8000"

// send to midi device, in this case a virtual midi port
@output midi_out MIDI "DAW Control 1"

// osc message coming in
@oscmsg

// look for a "fader_vol" message
oscmatch("/fader_vol") ? (

// store the value into a variable
v = oscparm(0);

// --- prepare midi message bytes ---

// 176 = 0xB0, ControlChange Message Channel 0
msg1 = 176;

// ControlChange Index 1, aka "Modwheel"
msg2= 1;

// touch osc sends osc message with a value between 0 and 1, float point
// multiply by 127, round it using |0, gets you a 7 bit value, 0 - 127
msg3 = (v*127)|0;

// send the midi message to all output midi devices available in the script
// this command always uses the msg1, msg2 and msg3 variables for its values
midisend(-1);

);
The code takes one specific osc message and sends it out as a 7-bit MIDI message. Thats what you wanted to achieve, isn't it? If so, this would be the place to start.

(Sorry about the formatting, code was way more readable in my text editor with all the colors and whatnot)
Fleeesch is offline   Reply With Quote
Old 07-07-2022, 08:50 PM   #10
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Hi. I'm a little stunned by this. I somehow thought we had to provide msg1, msg2 and msg3 with Hex code, hence the title of my post ha ha.

I didn't realize we can just feed integers to msg1,2 & 3. Wow.

So now I'm getting full midi conversion at the moment. Thanks so much!

------

One odd thing. These don't work for me:
Code:
note     = oscparm(0); 
velocity = oscparm(1);
I get unknown numbers in my DAW from using these. I see other people using that kind of coding but I can't get the expected result.

I have to use this to get any OSC parameters:
Code:
oscparm(0,'s',#note);
oscparm(1,'s',#velocity);
Any idea why? Thanks.
procedure is offline   Reply With Quote
Old 07-08-2022, 01:12 AM   #11
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

Seems to be an issue with the way how the incoming OSC message is structured.

AFAIk an OSC message goes like this <string>identifier <par1> parameter 1 <par2> parameter 2 ...

So TouchOSC should send something like ["note on"][60][127], meaning "active note 60 at full velocity".

If this code
Code:
oscparm(0,'s',#note);
oscparm(1,'s',#velocity);
gives you the actual data in string format it would mean that TouchOSC is sending its parameters as strings and not as float point numbers or integers.

You're using the new version of TouchOSC, aren't you? I only have the MK1 version, no options in the output format there. Maybe they've changed it with the release of the new version, added some options.

One quick solution would be to convert the strings to numbers, try this:
Code:
match("%i",#note,note)
This method converts #note to an integer ("%i" = format mask) and stores it in the "note" variable.
Fleeesch is offline   Reply With Quote
Old 07-08-2022, 11:39 AM   #12
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

I use the new version of TouchOSC, which is free to try indefinitely fyi. I can choose to send out strings, integers or floats from TouchOSC.

I tried to send out integers (as well as floats), but I cannot get OSCii-bot to read the OSC parameters when I code it like this:
Code:
oscparm(0,'i',note); //integer
oscparm(1,'i',velocity); //integer
This does work if I send out strings from TouchOSC:
Code:
oscparm(0,'s',#note); //string
oscparm(1,'s',#velocity); //string

But I tried this code you suggested and I can read integers from TouchOSC directly now:
Code:
n = oscparm(0);
v = oscparm(1);
You have been very helpful. Thank you.
procedure is offline   Reply With Quote
Old 07-08-2022, 01:55 PM   #13
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

You're welcome, glad I could help you out.
Fleeesch is offline   Reply With Quote
Old 07-14-2022, 10:42 AM   #14
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Thanks again for you help.
This was my final working script and was tested using the free version of TouchOSC, LoopBe, and FL Studio. It converts OSC from a controller such as TouchOSC and sends Midi through LoopBe to a DAW. It can send NoteOn, NoteOff, and ControlChange. I couldn't get SysEx working:

Code:
@input osc_in OSC "*:7001"     //Set this for your input
@output midi_out MIDI "LoopBe" //Set this for your output device

@init
@timer
@oscmsg

//TouchOSC - Receive 2 Integer OSC parameters to send out as Midi. 
oscmatch("*Note*",$'s') ? (//only works if finds OSC message named Note (or /NoteOn/ or /NoteOff/ etc)
	oscparm(idx,type);
	type=='i' ? (
		
		oscmatch("*NoteOn*",$'s') ? ( msg1 = 0x99 ) : ( msg1 = 0x83 );//noteon 0x99 or noteoff 0x83
		msg2 = oscparm(0); //middle c 0x3C
		msg3 = oscparm(1); //volume 127 0x7F

		midisend(midi_out);
		
	);
);

//TouchOSC - Control Change messages use Channel (1-16) and Ctrl (0-127) and a Value (0-127)
oscmatch("*ControlChange*",$'s') ? (
	oscparm(idx,type);
	type=='i' ? (
		
		msg1 = 0xB0;// 176 = 0xB0 Ch 1, 0xB1 Ch 2, 0xB2 Ch 3,... 0xBF ch 16
		msg2 = oscparm(0); //Ctrl number 0-127
		msg3 = oscparm(1); //value 0-127

		midisend(midi_out);
		
	);
);
	
//SYSEX -- NOT WORKING FOR ME
//if a SysEx (system exclusive) message is received, msg1/msg2/msg3 will all be 0, and oscstr will be set to a string with the SysEx data
//midisend_str(midiout, "\xF0\x00\x01\x02\xF7") example of sending SysEx -- all begin with 0xF0 (status byte that means this is sysex), then manufacturer ID, then 2 pieces of data, and end with 0xF7 to end message
//Universal messages -- There are two universal IDs that can be used by system exclusive messages instead of the specific manufacturer IDs Real time 0x7E (126) or Non-real time 0x7F (127)
//http://www.gweep.net/~prefect/eng/reference/protocol/midispec.html#Pgm
//https://www.recordingblogs.com/wiki/midi-system-exclusive-message
//Midi Song Start 0xFA, Continue 0xFB, Stop 0xFC
oscmatch("*xF0*",$'s') ? (
		midisend_str(midi_out, oscstr);
		
);
procedure is offline   Reply With Quote
Old 08-01-2022, 01:23 PM   #15
Fleeesch
Human being with feelings
 
Fleeesch's Avatar
 
Join Date: Apr 2011
Location: Germany
Posts: 175
Default

I hope the solution serves you well. Did you make any progress regarding SysEx messages?

Your problem kinda got me interested in the OSC protocol again, right now I'm trying to implement it myself into my setup. It sure has its advantages, especially when you want to adress a lot of stuff that needs to be controlled.

System Exclusive is another can of worms. Gotta be honest, there was never a case where I was required to receive SysEx, it was only a matter of sending a SysEx message to batch program RGB LEDs, hardware settings, etc. My plan is to receive larger OSC messages to program a hardware control surface, but I have no idea how to do it properly right now because of my lack of experience.
Fleeesch is offline   Reply With Quote
Old 08-01-2022, 01:37 PM   #16
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Sounds like an interesting project...

No I never did get SysEx working. Maybe if no one responds here, you could do a separate post asking about SysEx.

The comment section of my code just above my SysEx section has all the info I learned regarding the subject. But there is so little detail about it in the OSCII-bot manual.

I was hoping to use a Real Time message 0x7E that could perform Midi Song Start 0xFA, Continue 0xFB, and Stop 0xFC (among other things). But had no luck.

Post a link here to your new post if you do that. Thanks!
procedure is offline   Reply With Quote
Old 01-23-2023, 12:21 PM   #17
dodster
Human being with feelings
 
Join Date: Jan 2023
Location: Batley
Posts: 1
Default

I was following this to a point but in the last post surely a string such as "0x7E" is not HEX?
dodster is offline   Reply With Quote
Old 01-23-2023, 07:30 PM   #18
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Yes, the format is "0x" + the hex code which is "7E" in this case.
procedure is offline   Reply With Quote
Old 04-27-2023, 03:10 AM   #19
Starshine
Human being with feelings
 
Join Date: Jan 2023
Posts: 57
Default

Looks like TouchOSC supports MIDI SysEx via scripting. https://hexler.net/touchosc/manual/script-examples
Starshine is offline   Reply With Quote
Old 04-27-2023, 11:04 AM   #20
procedure
Human being with feelings
 
Join Date: Jun 2022
Posts: 11
Default

Thanks Starshine.
But I want this workflow:

TouchOSC --> OSCII-bot --> LoopBe --> DAW (FL Studio or other)

I'm only using TouchOSC as a testing tool. I want to build a midi app in Unity that can communicate with my DAW. So to get SysEX messages to my DAW, OSCII-bot has to transmit them.

Of course I'm completely open to other workflows. I would rather have Unity communicate directly with my DAW so that I don't have to run OSCII-Bot and LoopBe at all! There are midi plugins for Unity but last time I looked (a few months ago) I couldn't send anything but Note ON and OFF and CC's out of Unity.
procedure 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 02:38 AM.


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