bspaans/python-mingus

midi_file_in.py - python3 compatibility problems

Closed this issue · 6 comments

This is a follow-up to Issue #58 "midi_file_in.py opens midi file in text mode".

After testing the changes made in the main branch, I have found the following problems.

Lines 221 & 222 use the single slash division operator.

In Python3 this returns a float which causes fp.read() to raise:

TypeError: 'float' object cannot be interpreted as an integer

Changing the statements to use the double slash division operator allows the code to continue.

However, when it reaches line 148:

thirtyseconds = self.bytes_to_int(d[3])

this calls line 226:

return int(binascii.b2a_hex(bytes), 16)

which raises:

TypeError: a bytes-like object is required, not 'int'

By now I was coming to the conclusion that midi_file_in.py has not been updated for python3. There may be other compatibility problems after this.

I have found an alternative way to save and load track information in my project, which doesn't use midi files, so I have not investigated this problem further.

Thanks for your feedback. I'm fixing these other issues now and taking a more thorough look at this. Indeed they weren't 100% ready for Python 3 — they weren't caught by automated migration tools and there are no automated tests for MIDI funcionality :(

@reticulatus I've successfully ran the example code in the midi_file_in module. The changes are already in the master branch. Could you please check if your problems are solved now?

Thank you @edudobay - I've run my code using the version from the master branch and it now works without throwing any exceptions.

The values in the data I read back from the midi file are the same as those that were written to the file, except all the duration values are shown as floats, not integers.

e.g. part of the original data: [0.0, 8, ['C-5', 'E-5', 'G-5']]
the same part of the output from midi_file_in.py: [0.0, 8.0, ['C-5', 'E-5', 'G-5']]

However, the version read back from the midi file does play OK and sounds the same as the original sequence.

Great! I'm not sure about how it was designed, but it seems reasonable that the values read from the file are always normalized as floats. In the future I'd like to take a closer look at those types because there are some inconsistencies here and there. But glad to know your issue's solved!

I'm trying to import midi files using this part of the library and this is crashing for me as well. Here's a sample:

>>> import mingus.midi.midi_file_in as midi_file_in
>>> midi_file_in.MIDI_to_Composition("midis/simple.mid")
Traceback (most recent call last):
  File "/Users/jkeesh/.virtualenvs/music/lib/python3.5/site-packages/mingus/midi/midi_file_in.py", line 182, in parse_midi_file_header
    if fp.read(4) != "MThd":
  File "/Users/jkeesh/.pyenv/versions/3.5.7/lib/python3.5/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 13: invalid continuation byte

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jkeesh/.virtualenvs/music/lib/python3.5/site-packages/mingus/midi/midi_file_in.py", line 44, in MIDI_to_Composition
    return m.MIDI_to_Composition(file)
  File "/Users/jkeesh/.virtualenvs/music/lib/python3.5/site-packages/mingus/midi/midi_file_in.py", line 69, in MIDI_to_Composition
    (header, track_data) = self.parse_midi_file(file)
  File "/Users/jkeesh/.virtualenvs/music/lib/python3.5/site-packages/mingus/midi/midi_file_in.py", line 379, in parse_midi_file
    header = self.parse_midi_file_header(f)
  File "/Users/jkeesh/.virtualenvs/music/lib/python3.5/site-packages/mingus/midi/midi_file_in.py", line 188, in parse_midi_file_header
    raise IOError("Couldn't read from file.")
OSError: Couldn't read from file.

I've been able to use other midi python libraries like mido to read these same midi files, and I've been able to use all the other parts of the minugs library so I think there are some lingering bugs in midi_file_in

Hi @jkeesh! Sorry for the delay. I hadn't made a tagged release for the fix, so if you installed it with pip install mingus you wouldn't get the latest changes. Now you can upgrade to 0.6.1 with pip install -U mingus.