Skip to content

Commit

Permalink
port to python3
Browse files Browse the repository at this point in the history
  • Loading branch information
dromer committed Nov 23, 2023
1 parent 3ec46d4 commit 4e1688b
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
steps:
- run: sudo sed -i -e "s/# \(deb.*universe.*\)/\1/g" /etc/apt/sources.list
- run: sudo apt-get update
- run: sudo apt-get install python2 python3 python3-pip clang-format
- run: sudo apt-get install python3 python3-pip clang-format
- run: pip3 install -U platformio
- uses: actions/checkout@v2
- run: make check_fmt
Expand Down
3 changes: 1 addition & 2 deletions 3rdparty/tools/README
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
Python tools for manipulating .syx and .mid files for firmware updates, wavetables upload, etc.
This code is released under a GPL3.0 license.

Note: this code has been modified by <[email protected]>. The original can be found at
Note: this code has been modified by <[email protected]> and Wasted Audio. The original can be found at
<https://github.com/pichenettes/avr-midi-bootloader/tree/baf39f16648a6bf865df3251d1bd66fcb0572fa9>.

Changed:
- in `tools/hex2sysex/hex2sysex.py`: Changed `default='\x00\x21\x02'` to `default='\x00\x21\x44'`.

27 changes: 14 additions & 13 deletions 3rdparty/tools/hex2sysex/hex2sysex.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python2.5
#!/usr/bin/python3
#
# Copyright 2009 Emilie Gillet.
#
Expand Down Expand Up @@ -69,7 +69,7 @@ def CreateMidifile(
# first SysEx block everytime stop/play is pressed.
time = 1
syx_data = []
for i in xrange(0, size, page_size):
for i in range(0, size, page_size):
block = ''.join(map(chr, data[i:i+page_size]))
padding = page_size - len(block)
block += '\x00' * padding
Expand All @@ -89,13 +89,13 @@ def CreateMidifile(
options.reset_command)
t.AddEvent(time, event)
syx_data.append(event.raw_message)
f = file(output_file, 'wb')
if options.syx:
f.write(''.join(syx_data))
else:
m.Write(f, format=1)
f.close()

with open(output_file, 'wb') as f:
if options.syx:
f.write(b''.join(syx_data))
else:
m.Write(f, format=1)
f.close()


if __name__ == '__main__':
Expand Down Expand Up @@ -173,10 +173,11 @@ def CreateMidifile(
logging.fatal('Specify one, and only one firmware .hex file!')
sys.exit(1)

data = hexfile.LoadHexFile(file(args[0]))
if not data:
logging.fatal('Error while loading .hex file')
sys.exit(2)
with open(args[0], 'r') as f:
data = hexfile.LoadHexFile(f.read().splitlines())
if not data:
logging.fatal('Error while loading .hex file')
sys.exit(2)

output_file = options.output_file
if not output_file:
Expand Down
10 changes: 5 additions & 5 deletions 3rdparty/tools/hexfile/hexfile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python2.5
#!/usr/bin/python3
#
# Copyright 2009 Emilie Gillet.
#
Expand Down Expand Up @@ -36,11 +36,11 @@ def LoadHexFile(lines):
logging.info('Line %(line_number)d: line too short' % locals())
return None

if not all(x in '0123456789abcdefABCDEF' for x in line[1:]):
if not all(str(x) in '0123456789abcdefABCDEF' for x in line[1:]):
logging.info('Line %(line_number)d: unknown character' % locals())
return None

bytes = [int(line[i:i+2], 16) for i in xrange(1, len(line), 2)]
bytes = [int(line[i:i+2], 16) for i in range(1, len(line), 2)]
if bytes[0] != len(bytes) - 5:
logging.info('Line %(line_number)d: invalid byte count' % locals())
return None
Expand Down Expand Up @@ -74,7 +74,7 @@ def LoadHexFile(lines):
def WriteHexFile(data, file_object, chunk_size=32):
"""Writes a Hex file."""

for address in xrange(0, len(data), chunk_size):
for address in range(0, len(data), chunk_size):
chunk = data[address:address+chunk_size]
chunk_len = len(chunk)
address_l = address & 255
Expand All @@ -83,4 +83,4 @@ def WriteHexFile(data, file_object, chunk_size=32):
file_object.write(''.join('%02x' % value for value in chunk))
checksum = (-(chunk_len + address_l + address_h + sum(chunk))) & 255
file_object.write('%02x\n' % checksum)
file_object.write(':00000001FF\n')
file_object.write(':00000001FF\n')
74 changes: 37 additions & 37 deletions 3rdparty/tools/midi/midifile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python2.5
#!/usr/bin/python3
#
# Copyright 2009 Emilie Gillet.
#
Expand Down Expand Up @@ -47,7 +47,7 @@ def PackVariableLengthInteger(value):
to_write = value & 0x7f
value = value >> 7
output.insert(0, to_write)
for i in xrange(len(output) - 1):
for i in range(len(output) - 1):
output[i] |= 0x80
output = ''.join(map(chr, output))
return output
Expand All @@ -58,7 +58,7 @@ def PackVariableLengthInteger(value):
class Event(object):
def __init__(self):
pass

def Serialize(self, running_status):
raise NotImplementedError

Expand All @@ -68,7 +68,7 @@ def __init__(self, id, data):
assert len(data) < 256
self.id = id
self.data = data

def Serialize(self, running_status):
return ''.join([
'\xff',
Expand Down Expand Up @@ -173,7 +173,7 @@ def __init__(self, mask, channel, data):
self.channel = channel
self._status = mask | (channel - 1)
self._data = PackInteger(self._status, size=1) + data

def Serialize(self, running_status):
if self._status == running_status:
return self._data[1:], self._status
Expand Down Expand Up @@ -238,7 +238,7 @@ def __init__(self, channel, pitch_bend_14_bits):
class SystemEvent(Event):
def __init__(self, id):
self._id = id

def Serialize(self, running_status):
return PackInteger(self._id, size=1), running_status

Expand Down Expand Up @@ -267,16 +267,16 @@ def __init__(self):
class SysExEvent(Event):
def __init__(self, manufacturer_id, device_id, data):
self.data = data
self.message = ''.join([
manufacturer_id,
self.message = b''.join([
manufacturer_id.encode('utf-8'),
device_id,
data,
'\xf7'])
self.raw_message = '\xf0' + self.message
assert all(ord(x) < 128 for x in self.message[:-1])
self.message = ''.join([
'\xf0',
PackVariableLengthInteger(len(self.message)),
data.encode('utf-8'),
b'\xf7'])
self.raw_message = b'\xf0' + self.message
# assert all(ord(x) < 128 for x in self.message[:-1])
self.message = b''.join([
b'\xf0',
PackVariableLengthInteger(len(self.message)).encode('utf-8'),
self.message])

def Serialize(self, running_status):
Expand All @@ -299,7 +299,7 @@ def Nibblize(data, add_checksum=True):
class Track(object):
def __init__(self):
self._events = []

def AddEvent(self, time, event):
self._events.append((time, event))

Expand All @@ -321,36 +321,36 @@ def Serialize(self):
data.append(event_data)
current_time = time
return ''.join(data)

def Write(self, file_object):
file_object.write('MTrk')
track_data = self.Serialize()
file_object.write(PackInteger(len(track_data)))
file_object.write(track_data)

@property
def events(self):
return self._events


class Writer(object):
def __init__(self, ppq=96):
self._tracks = []
self._ppq = ppq

def AddTrack(self):
new_track = Track()
self._tracks.append(new_track)
return new_track

def _MergeTracks(self):
new_track = Track()
for track in self._tracks:
for time_event in track.events:
new_track.AddEvent(*time_event)
new_track.Sort()
return new_track

def Write(self, file_object, format=0):
tracks = self._tracks
if format == 0:
Expand All @@ -365,7 +365,7 @@ def Write(self, file_object, format=0):
else:
file_object.write(PackInteger(len(self._tracks), size=2))
file_object.write(PackInteger(self._ppq, size=2))

# Tracks.
for track in tracks:
track.Write(file_object)
Expand All @@ -377,7 +377,7 @@ def __init__(self):
self.format = 0
self.ppq = 96
self._previous_status = 0

def Read(self, f):
assert f.read(4) == 'MThd'
assert struct.unpack('>i', f.read(4))[0] == 6
Expand All @@ -386,12 +386,12 @@ def Read(self, f):
num_tracks = struct.unpack('>h', f.read(2))[0]
self.ppq = struct.unpack('>h', f.read(2))[0]
self._tempo_map = []
for i in xrange(num_tracks):

for i in range(num_tracks):
self.tracks.append(self._ReadTrack(f))
self._CreateCumulativeTempoMap()


def _ReadTrack(self, f):
assert f.read(4) == 'MTrk'
size = struct.unpack('>i', f.read(4))[0]
Expand All @@ -406,7 +406,7 @@ def _ReadTrack(self, f):
self._tempo_map.append((t, e.bpm))
size -= event_size
return events

def _CreateCumulativeTempoMap(self):
t = 0.0
current_tempo = 120.0
Expand All @@ -419,13 +419,13 @@ def _CreateCumulativeTempoMap(self):
current_tempo = tempo
previous_beat = beat
self._tempo_map = cumulative_tempo_map

def AbsoluteTime(self, t):
index = bisect.bisect_left(self._tempo_map, (t, 0, 0))
index = max(index - 1, 0)
start_beat, start_seconds, tempo = self._tempo_map[index]
return start_seconds + float(t - start_beat) / self.ppq * 60.0 / tempo

def _ReadVariableLengthInteger(self, f):
v = 0
size = 0
Expand All @@ -437,7 +437,7 @@ def _ReadVariableLengthInteger(self, f):
if not (byte & 0x80):
break
return v, size

def _ReadEvent(self, f):
delta_t, size = self._ReadVariableLengthInteger(f)
event_byte = ord(f.read(1))
Expand All @@ -449,7 +449,7 @@ def _ReadEvent(self, f):
event_byte = self._previous_status
else:
return delta_t, None, size

event_type = event_byte & 0xf0
channel = event_byte & 0xf
channel += 1
Expand Down Expand Up @@ -527,22 +527,22 @@ def _ReadEvent(self, f):
size += event_size
event = SysExEvent(bytes[0:3], bytes[3:5], bytes[5:-1])
else:
print event_byte, '!!'
print(event_byte, '!!')
event = None
return delta_t, event, size


if __name__ == '__main__':
m = Writer()
t = m.AddTrack()
t.AddEvent(0, TempoEvent(120.0))

t = m.AddTrack()
t.AddEvent(1, SysExEvent(
'\x00\x20\x77',
'\x00\x01',
'\x7f\x7f' + Nibblize('\xff\x00\xcc')))

f = file('output.mid', 'wb')
m.Write(f, format=0)
f.close()
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ check_fmt:
touch $@ # because platformio is strange

firmware.syx: .pio/build/ATmega1284P/firmware.hex
PYTHONPATH=3rdparty python2 3rdparty/tools/hex2sysex/hex2sysex.py -s -o $@ -v 0x7f $<
PYTHONPATH=3rdparty python3 3rdparty/tools/hex2sysex/hex2sysex.py -s -o $@ -v 0x7f $<

clean:
platformio run -t clean
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A million thanks to [Matt Montag](https://github.com/mmontag) & [Florian Jung](h

## Building and flashing the source code:

Install `platformio` and `python2`. (Yes. I am so sorry :(.)
Install `platformio`.

To compile the firmware and to generate the firmware update sysex, run:

Expand Down Expand Up @@ -40,4 +40,3 @@ Thank you, we are looking forward to your contribution! :)
The MEGAfm firmware under `src/` and `include/` is free software. It is released under the terms of
the [ISC License](LICENSE.md). The libraries and tools distributed in the `3rdparty/` and `lib/`
directories have their own copyright and license notes.

2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ platform = atmelavr
board = ATmega1284P
framework = arduino
upload_protocol = custom
upload_command = PYTHONPATH=./bootloaderT python bootloaderT/tools/hex2sysex/hex2sysex.py --syx -o firmware.syx .pio/build/ATmega1284P/firmware.hex
upload_command = PYTHONPATH=./3rdparty python 3rdparty/tools/hex2sysex/hex2sysex.py --syx -o firmware.syx .pio/build/ATmega1284P/firmware.hex
; TODO(montag): find an alternative to sendmidi (it doesn't throttle sysex)
; sendmidi dev "mio" syf firmware.syx
build_unflags = -flto
Expand Down

0 comments on commit 4e1688b

Please sign in to comment.