2

I have type 0 MIDI file, containing the track with only 269 meta-messages that I'd like to keep the header chunk and the last one for the end of the file.

for i, msg in enumerate(mid.tracks[0]):
    if i > 10 or i < len(mid.tracks[0])-1:
        if msg.is_meta:
            mid.tracks[0].pop(i)

The above code, does not do this. In fact, it removes exactly half of the messages (135 of them), it also removes the beginning and the end and I have to runs it a few times to get it to close to 10 meta messages!

The library says:

pop([index]) → item -- remove and return item at index (default last). Raises IndexError if list is empty or index is out of range.

I also tried another way, but again, each time only removes half of that. So I need to runs the loop few times to get it close to size I want:

while len(mid.tracks[0])>16:
    for i, msg in enumerate(mid.tracks[0]):
        if msg.is_meta and hasattr(msg, 'data'): 
            if len(msg.data) == 7:
                mid.tracks[0].remove(msg)

for i, msg in enumerate(mid.tracks[0]):
    if msg.is_meta:
        print(i, msg)

What am I doing wrong please?

chikitin
  • 762
  • 6
  • 28
  • 1
    You really should not modify an object inside a loop over the object. When you call `pop(i)` you setting yourself up for trouble. Perhaps create a "remove" list and remove them seperately. – F Trias Apr 19 '20 at 21:33
  • It seems it pops randomly! I just did that. and edited the OP. Thank you the answer. – chikitin Apr 19 '20 at 21:34
  • could you please comment on this as well: https://stackoverflow.com/questions/61305523/adding-midi-chords-at-specific-metamessage-time . I really appreciate it. – chikitin Apr 19 '20 at 21:35

1 Answers1

0

Something like this might be faster. Note, the code may not match your data exactly. If you post your value of mid.tracks[0], I can give you a better result.

t = mid.tracks[0] # shorthand to simplify code
keep = t[:10] + t[-1:] # get first ten and last one
# keep only the non-meta ones
result = [msg for msg in keep if not msg.is_meta]

Note: revised according to comment.

F Trias
  • 189
  • 8
  • your second line: TypeError: can only concatenate list (not "MetaMessage") to list! – chikitin Apr 19 '20 at 21:51
  • Try `t[-1:]` instead of `t[-1]`. If not, then try `[t[-1]]`. It all depends on what exactly is in you `mid.tracks[0]` object. Perhaps you can post a dump of the object? – F Trias Apr 20 '20 at 12:38