magenta / note-seq

A serializable note sequence representation and utilities.
Apache License 2.0
213 stars 57 forks source link

MIDI End Of Track meta message always in Channel 1 #39

Closed thomasarvanitidis closed 3 years ago

thomasarvanitidis commented 3 years ago

When you import the following generated MIDI file in a DAW (I work with REAPER), the DAW asks whether to expand the 2 MIDI tracks to new session tracks. However, I am programming a single track with all notes in channel 10. AFAIU, this happens because the MIDI end of track meta message is automatically inserted in channel 1 by note_seq. Is there a way to manually insert the end of track meta message or manipulate it programmatically?

I have searched for NoteSequence creation in magenta and note-seq, but didn't managed to find anything related. I was also unlucky reading the note_seq/protobuf/music_pb2.py. Using note-seq 0.0.3.

import note_seq
# Create a simple drum loop.
ns = note_seq.NoteSequence(ticks_per_quarter=note_seq.STANDARD_PPQ)
ns.tempos.add(qpm=120)
ns.notes.add( # Step 1: Kick
    instrument=9, program=0, is_drum=True, pitch=36, velocity=127, start_time=0, end_time=0.125)
ns.notes.add( # Step 2: Snare
    instrument=9, program=0, is_drum=True, pitch=38, velocity=127, start_time=0.5, end_time=0.625)
ns.notes.add( # Step 3: Kick
    instrument=9, program=0, is_drum=True, pitch=36, velocity=127, start_time=1, end_time=1.125)
ns.notes.add( # Step 4: Snare
    instrument=9, program=0, is_drum=True, pitch=38, velocity=127, start_time=1.5, end_time=1.625)
# Export MIDI file.
note_seq.sequence_proto_to_midi_file(ns, "simple.mid")

Screenshot 2021-05-13 at 12 46 55

cghawthorne commented 3 years ago

Hi @thomasarvanitidis. note-seq uses pretty-midi to turn NoteSequences into midi files. It looks like pretty-midi uses a separate "timing track" for things like the end_of_track message, which explains what you're seeing: https://github.com/craffel/pretty-midi/blob/master/pretty_midi/pretty_midi.py#L1377

If you need to manipulate low-level MIDI events like this message, I'd suggest using pretty-midi or mido directly. If it's helpful, you can convert a NoteSequence to a pretty-midi object with the note_sequence_to_pretty_midi method.