2021-12-01

Porting LiveOSC different result of struct.pack in py2 & py3

being right in the middle of porting LiveOSC/OSC.py to work with Ableton Live 11xx

my implementation of the Midi Remote Script ported to python3+ is working and compiles properly and shows up in RemoteScript Menu, means i can nail down my problem to the following..

python2 starting at Line:188 python3 (my code for this particular piece)
•••
if type(next) == type("") \
or type(next) == type(unicode()):
if (type(next) == type(unicode())):
next = str(next)
padlen = math.ceil((len(next)+1) / 4.0) * 4
binary = struct.pack(">%ds" % padlen, next)
•••
•••
if type(next) == type("") \
or type(next) == type(str()):
if (type(next) == type(str())):
next = next.encode()
padlen = math.ceil((len(next)+1) / 4.0) * 4
binary = struct.pack(">%ds" % padlen, next)
•••
input: /foo/play input: /foo/play
resulting binary pack will look like:
/foo/play
resulting binary pack will look like:
/foo/play\x00\x00\x00
hexdump will look like:
2f 66 6f 6f 2f 70 6c 61 '/foo/pla'
79 0 0 0 __ __ __ __ 'y\x00\x00\x00'
__ __ __ __ __ __ __ __
hexdump will look like:
2f 66 6f 6f 2f 70 6c 61 '/foo/pla'
79 5c 78 30 30 5c 78 30 'y\\x00\\x0'
30 5c 78 30 30 __ __ __ '0\\x00'
will work with Ableton Live 10, not 11
OSC protocol working properly
should work with Ableton Live 11, not 10
OSC protocol throws error: wrong alignment, invalid data when i try to receive this data via network

The changes introduced by python3 are messing up the alignment and conversion of pack. The encoding appears in the byte stream which is wrong because in OSC those are malicious non-aligned data like \ or b'xyz'.

I know i can cut out those parts after but the aligment and/or the data is messed up then either.

As pack takes bytes as argument object, i just cant find a way to do this properly..

See the extra \ in \\x00 visible in hexdump. What i am missing? OSC send & receiving is usually a stream of utf-8 strings which fits to pythons default encoding why does struct.pack in py3 have extra \\ escaping?.

Edit: i placed some extra prints in the build steps of the first testMessage.
With python2 it builds up like this..

/foo/play,
/foo/play,i,
/foo/play,ii,

/foo/play,iif,
              @?
/foo/play,iifs,
               @?the white cliffs of dover

with python3

/foo/play\x00\x00\x00,\x00\x00\x00
/foo/play\x00\x00\x00,i\x00\x00\x00\x00\x00,
/foo/play\x00\x00\x00,ii\x00\x00\x00\x00,\x00\x00\x00\x0b
/foo/play\x00\x00\x00,iif\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x0b@\x90\x00\x00
/foo/play\x00\x00\x00,iifs\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x0b@\x90\x00\x00the white cliffs of dover\x00\x00\x00


from Recent Questions - Stack Overflow https://ift.tt/3GhJu7h
https://ift.tt/eA8V8J

No comments:

Post a Comment