![]() |
#1 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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); ); ); Thank you. Last edited by procedure; 07-07-2022 at 09:45 AM. |
![]() |
![]() |
![]() |
#2 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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? |
![]() |
![]() |
![]() |
#3 |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
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); #input : input string containing your OSC value output_value : variable that gets to store the value for MIDI output |
![]() |
![]() |
![]() |
#4 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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"); ); ); /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. |
![]() |
![]() |
![]() |
#5 |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
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) 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. 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. |
![]() |
![]() |
![]() |
#6 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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 ![]() --------------------- 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. |
![]() |
![]() |
![]() |
#7 |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
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. |
![]() |
![]() |
![]() |
#8 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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. |
![]() |
![]() |
![]() |
#9 | |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
I did some trial and error using my old version of TouchOSC. Take a look:
Quote:
(Sorry about the formatting, code was way more readable in my text editor with all the colors and whatnot) |
|
![]() |
![]() |
![]() |
#10 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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 have to use this to get any OSC parameters: Code:
oscparm(0,'s',#note); oscparm(1,'s',#velocity); |
![]() |
![]() |
![]() |
#11 |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
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); 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) |
![]() |
![]() |
![]() |
#12 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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 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); |
![]() |
![]() |
![]() |
#13 |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
You're welcome, glad I could help you out.
|
![]() |
![]() |
![]() |
#14 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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); ); |
![]() |
![]() |
![]() |
#15 |
Human being with feelings
Join Date: Apr 2011
Location: Germany
Posts: 156
|
![]()
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. |
![]() |
![]() |
![]() |
#16 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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! |
![]() |
![]() |
![]() |
#17 |
Human being with feelings
Join Date: Jan 2023
Location: Batley
Posts: 1
|
![]()
I was following this to a point but in the last post surely a string such as "0x7E" is not HEX?
|
![]() |
![]() |
![]() |
#18 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
Yes, the format is "0x" + the hex code which is "7E" in this case.
|
![]() |
![]() |
![]() |
#19 |
Human being with feelings
Join Date: Jan 2023
Posts: 56
|
![]()
Looks like TouchOSC supports MIDI SysEx via scripting. https://hexler.net/touchosc/manual/script-examples
|
![]() |
![]() |
![]() |
#20 |
Human being with feelings
Join Date: Jun 2022
Posts: 11
|
![]()
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. |
![]() |
![]() |
![]() |
Thread Tools | |
Display Modes | |
|
|