I am using pythonista on ios to generate some midi values but the rtmidi library can't be installed for ios and none of the other pyhton midi libraries are in pure python ( a requirement for pythonista packages) so it sounds like osc might be the best way to get midi out from pythonista. I am able to get an osc message sent out to touchosc and get it to toggle a pad off and on but now I'd like to understand how I can use the OSC module in midifire. To be honest I am just learning what sysex is and that midifire is taking an osc message and formatting it into a proper sysex message but I don't know exactly how to use it. Is it possible to get a basic example file showing how to take an osc message and make it into a midi note on and send it to a midi port. I am hoping if I saw how to do that I could build off of it. If you have any other thoughts on how I might be able to send midi out from pythonista I'd love to get your advice since clearly you know it all when it comes to midi and ios. thanks
Let me check I have this correct. iOS pythonista cannot see any MIDI ports at all (physical, virtual, network, bluetooth) but it can send a UDP packet to a host and destination? Or can it just not see the wifi port? I think it is the former (no ports at all) from your description.
What is the final destination for the MIDI messages? Maybe there is a different way than what I describe below.
MidiFire's OSC Exchange module will actually accept any data (does not need to be OSC) so in theory you could just pipe your unaltered MIDI messages to it (one per packet for simplicity) and then unpack the resultant sysex and forward the MIDI to wherever you need in MidiFire (any MIDI port).
The tricky part is unpacking (decoding 7 bit back to 8 bit) the MIDI message from the sysex, though. It should be possible to write some Stream Byter code to do this.
Here is how the encoding works:
OSC Exchange adds an additional byte every 7 bytes to store the MSB of every value. So 7 values look like this:
So, the Stream Byter code would need to reverse that encoding and then the original message could be assembled.If you were only sending non-sysex messages to start with, this code could be quite simple. If not, then it's a little more complex.
That's the gist of how I would approach the problem. If you didn't want to write Stream Byter code (and it's admittedly a non trivial exercise) then I could probably have a go some time.
Wow this is great and so informative. I can't wait to try it. To answer your question regarding pythonista and midi it can't see any ports but in the forum they are suggesting to use midifire as noted in this post forum.omz-software.com/topic/4506/midi. Pythonista is a well developed app and it has a good sized user base that are, according to multiple midi related posts on the forum, very interested in using midi. Not sure if this makes sense but it might be worth looking into as I bet you can find a way and perhaps there is an app that can address the current limitations. thanks again
Just to follow up on this. I tested my code above this morning and it seems to work fine. I will point out that from the python script that the MIDI message must be sent as binary to the UDP port, so each udp packet will be 1, 2 or 3 bytes depending upon the MIDI message you are sending. If you send it a text string it won't work.
To send MIDI from MidiFire back to a script via udp, you would do the reverse operation and feed incoming MIDI messages into a Stream Byter with these rules and then onto OSC Exchange configured to send on a specific udp port:
# pack for osc exchange IF ML <= 3 MAT M0 = M0 - 80 SND F0 5A 01 M0 M1 M2 F7 XX = XX +B END
Naturally, the python script must be listening on that udp port, and each MIDI message will be received as a separate binary packet
> it has a good sized user base that are, according to multiple midi related posts on the forum, very interested in using midi.
So, this method works and will allow you to push/pull MIDI events to CoreMIDI via udp (mac or ios for that matter) from any scripting (or compiled) language pretty easily using MidiFire as a bridge between CoreMIDI.
I could have a go at making up a MidiFire scene and posting it here that does bi-directional udp/CoreMIDI conversion to make it easy to deploy. If anyone would like this - please let me know.
If I'm made aware of a demand to be able to also handle sysex with this method then I might consider writing packing/unpacking routines in Stream Byter that will work with that too, but for now, just non-sysex messages.
Here is some code for Pythonista using UDP to MidiFire #https://adamsiembida.com/how-to-send-a-udp-packet-in-python/ import socket
# addressing information of target #fill in your ip and port IPADDR = '127.0.0.1' PORTNUM = 8051
# enter the data content of the UDP packet as hex msg1 = bytearray([0x90, 0x40, 0x60]) msg2 = bytes.fromhex('903e70') #or using variable for midi note message midi_message = '903c50' midi_packet = bytes.fromhex(midi_message)
# initialize a socket, think of it as a cable # SOCK_DGRAM specifies that this is UDP s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
try: # connect the socket, think of it as connecting the cable to the address location s.connect((IPADDR, PORTNUM))
# send the command s.send(midi_packet) s.send(msg1) s.send(msg2) # close the socket except: pass # close the socket s.close()