# Path: note_seq/constants.py
# DEFAULT_QUARTERS_PER_MINUTE = 120.0
# DEFAULT_STEPS_PER_BAR = 16  # 4/4 music sampled at 4 steps per quarter note.
# DEFAULT_STEPS_PER_QUARTER = 4
# DEFAULT_STEPS_PER_SECOND = 100
# STANDARD_PPQ = 220
# NUM_SPECIAL_MELODY_EVENTS = 2
# MELODY_NOTE_OFF = -1
# MELODY_NO_EVENT = -2
# MIN_MELODY_EVENT = -2
# MAX_MELODY_EVENT = 127
# MIN_MIDI_PITCH = 0  # Inclusive.
# MAX_MIDI_PITCH = 127  # Inclusive.
# NUM_MIDI_PITCHES = MAX_MIDI_PITCH - MIN_MIDI_PITCH + 1
# NOTES_PER_OCTAVE = 12
# MIN_MIDI_VELOCITY = 1  # Inclusive.
# MAX_MIDI_VELOCITY = 127  # Inclusive.
# MIN_MIDI_PROGRAM = 0
# MAX_MIDI_PROGRAM = 127
# UNPITCHED_PROGRAMS = (
#     list(range(96, 104)) + list(range(112, 120)) + list(range(120, 128)))
# NO_CHORD = 'N.C.'
# MAJOR_SCALE = [0, 2, 4, 5, 7, 9, 11]
# NOTE_KEYS = [
#     [0, 1, 3, 5, 7, 8, 10],
#     [1, 2, 4, 6, 8, 9, 11],
#     [0, 2, 3, 5, 7, 9, 10],
#     [1, 3, 4, 6, 8, 10, 11],
#     [0, 2, 4, 5, 7, 9, 11],
#     [0, 1, 3, 5, 6, 8, 10],
#     [1, 2, 4, 6, 7, 9, 11],
#     [0, 2, 3, 5, 7, 8, 10],
#     [1, 3, 4, 6, 8, 9, 11],
#     [0, 2, 4, 5, 7, 9, 10],
#     [1, 3, 5, 6, 8, 10, 11],
#     [0, 2, 4, 6, 7, 9, 11]
# ]
# 
# Path: note_seq/midi_io.py
# _PRETTY_MIDI_MAJOR_TO_MINOR_OFFSET = 12
# class MIDIConversionError(Exception):
# def midi_to_note_sequence(midi_data):
# def midi_file_to_note_sequence(midi_file):
# def note_sequence_to_midi_file(sequence, output_file,
#                                drop_events_n_seconds_after_last_note=None):
# def note_sequence_to_pretty_midi(
#     sequence, drop_events_n_seconds_after_last_note=None):
# def midi_to_sequence_proto(midi_data):
# def sequence_proto_to_pretty_midi(sequence,
#                                   drop_events_n_seconds_after_last_note=None):
# def midi_file_to_sequence_proto(midi_file):
# def sequence_proto_to_midi_file(sequence, output_file,
#                                 drop_events_n_seconds_after_last_note=None):
# 
# Path: note_seq/testing_lib.py
# BEAT = music_pb2.NoteSequence.TextAnnotation.BEAT
# CHORD_SYMBOL = music_pb2.NoteSequence.TextAnnotation.CHORD_SYMBOL
# def add_track_to_sequence(note_sequence,
#                           instrument,
#                           notes,
#                           is_drum=False,
#                           program=0):
# def add_chords_to_sequence(note_sequence, chords):
# def add_key_signatures_to_sequence(note_sequence, keys):
# def add_beats_to_sequence(note_sequence, beats, beats_per_bar=None):
# def add_control_changes_to_sequence(note_sequence, instrument, control_changes):
# def add_pitch_bends_to_sequence(
#     note_sequence, instrument, program, pitch_bends):
# def add_quantized_steps_to_sequence(sequence, quantized_steps):
# def add_quantized_chord_steps_to_sequence(sequence, quantized_steps):
# def add_quantized_control_steps_to_sequence(sequence, quantized_steps):
#   def __init__(self, num_classes, num_steps=None):
#   def num_classes(self):
#   def default_event(self):
#   def encode_event(self, event):
#   def decode_event(self, index):
#   def event_to_num_steps(self, event):
# def parse_test_proto(proto_type, proto_string):
# def get_testdata_dir():
#   def setUp(self):
#   def _AssertProtoEquals(self, a, b, msg=None):  # pylint:disable=invalid-name
#   def assertProtoEquals(self, expected_message_maybe_ascii, message, msg=None):
# class TrivialOneHotEncoding(encoder_decoder.OneHotEncoding):
# class ProtoTestCase(absltest.TestCase):


import collections
import os.path
import tempfile
import mido
import pretty_midi
from absl.testing import absltest
from note_seq import constants
from note_seq import midi_io
from note_seq import testing_lib
from note_seq.protobuf import music_pb2
_SIMPLE_MIDI_FILE_NUM_NOTES = 8
_SIMPLE_MIDI_FILE_SUSTAIN = .95

# self.midi_complex_filename contains many instruments including percussion as
# well as control change and pitch bend events.

# self.midi_is_drum_filename contains 41 tracks, two of which are on channel 9.

# self.midi_event_order_filename contains notes ordered
# non-monotonically by pitch.  Here are relevent events as printed by
# mididump.py:
#   midi.NoteOnEvent(tick=0, channel=0, data=[1, 100]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[3, 100]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[2, 100]),
#   midi.NoteOnEvent(tick=4400, channel=0, data=[3, 0]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[1, 0]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[2, 0]),


class MidiIoTest(absltest.TestCase):

  def setUp(self):
    super().setUp()
    self.midi_simple_filename = os.path.join(
        testing_lib.get_testdata_dir(), 'example.mid')
    self.midi_complex_filename = os.path.join(
        testing_lib.get_testdata_dir(), 'example_complex.mid')
    self.midi_is_drum_filename = os.path.join(
        testing_lib.get_testdata_dir(), 'example_is_drum.mid')
    self.midi_event_order_filename = os.path.join(

# Path: note_seq/constants.py
# DEFAULT_QUARTERS_PER_MINUTE = 120.0
# DEFAULT_STEPS_PER_BAR = 16  # 4/4 music sampled at 4 steps per quarter note.
# DEFAULT_STEPS_PER_QUARTER = 4
# DEFAULT_STEPS_PER_SECOND = 100
# STANDARD_PPQ = 220
# NUM_SPECIAL_MELODY_EVENTS = 2
# MELODY_NOTE_OFF = -1
# MELODY_NO_EVENT = -2
# MIN_MELODY_EVENT = -2
# MAX_MELODY_EVENT = 127
# MIN_MIDI_PITCH = 0  # Inclusive.
# MAX_MIDI_PITCH = 127  # Inclusive.
# NUM_MIDI_PITCHES = MAX_MIDI_PITCH - MIN_MIDI_PITCH + 1
# NOTES_PER_OCTAVE = 12
# MIN_MIDI_VELOCITY = 1  # Inclusive.
# MAX_MIDI_VELOCITY = 127  # Inclusive.
# MIN_MIDI_PROGRAM = 0
# MAX_MIDI_PROGRAM = 127
# UNPITCHED_PROGRAMS = (
#     list(range(96, 104)) + list(range(112, 120)) + list(range(120, 128)))
# NO_CHORD = 'N.C.'
# MAJOR_SCALE = [0, 2, 4, 5, 7, 9, 11]
# NOTE_KEYS = [
#     [0, 1, 3, 5, 7, 8, 10],
#     [1, 2, 4, 6, 8, 9, 11],
#     [0, 2, 3, 5, 7, 9, 10],
#     [1, 3, 4, 6, 8, 10, 11],
#     [0, 2, 4, 5, 7, 9, 11],
#     [0, 1, 3, 5, 6, 8, 10],
#     [1, 2, 4, 6, 7, 9, 11],
#     [0, 2, 3, 5, 7, 8, 10],
#     [1, 3, 4, 6, 8, 9, 11],
#     [0, 2, 4, 5, 7, 9, 10],
#     [1, 3, 5, 6, 8, 10, 11],
#     [0, 2, 4, 6, 7, 9, 11]
# ]
# 
# Path: note_seq/midi_io.py
# _PRETTY_MIDI_MAJOR_TO_MINOR_OFFSET = 12
# class MIDIConversionError(Exception):
# def midi_to_note_sequence(midi_data):
# def midi_file_to_note_sequence(midi_file):
# def note_sequence_to_midi_file(sequence, output_file,
#                                drop_events_n_seconds_after_last_note=None):
# def note_sequence_to_pretty_midi(
#     sequence, drop_events_n_seconds_after_last_note=None):
# def midi_to_sequence_proto(midi_data):
# def sequence_proto_to_pretty_midi(sequence,
#                                   drop_events_n_seconds_after_last_note=None):
# def midi_file_to_sequence_proto(midi_file):
# def sequence_proto_to_midi_file(sequence, output_file,
#                                 drop_events_n_seconds_after_last_note=None):
# 
# Path: note_seq/testing_lib.py
# BEAT = music_pb2.NoteSequence.TextAnnotation.BEAT
# CHORD_SYMBOL = music_pb2.NoteSequence.TextAnnotation.CHORD_SYMBOL
# def add_track_to_sequence(note_sequence,
#                           instrument,
#                           notes,
#                           is_drum=False,
#                           program=0):
# def add_chords_to_sequence(note_sequence, chords):
# def add_key_signatures_to_sequence(note_sequence, keys):
# def add_beats_to_sequence(note_sequence, beats, beats_per_bar=None):
# def add_control_changes_to_sequence(note_sequence, instrument, control_changes):
# def add_pitch_bends_to_sequence(
#     note_sequence, instrument, program, pitch_bends):
# def add_quantized_steps_to_sequence(sequence, quantized_steps):
# def add_quantized_chord_steps_to_sequence(sequence, quantized_steps):
# def add_quantized_control_steps_to_sequence(sequence, quantized_steps):
#   def __init__(self, num_classes, num_steps=None):
#   def num_classes(self):
#   def default_event(self):
#   def encode_event(self, event):
#   def decode_event(self, index):
#   def event_to_num_steps(self, event):
# def parse_test_proto(proto_type, proto_string):
# def get_testdata_dir():
#   def setUp(self):
#   def _AssertProtoEquals(self, a, b, msg=None):  # pylint:disable=invalid-name
#   def assertProtoEquals(self, expected_message_maybe_ascii, message, msg=None):
# class TrivialOneHotEncoding(encoder_decoder.OneHotEncoding):
# class ProtoTestCase(absltest.TestCase):


# Path: note_seq/midi_io_test.py
import collections
import os.path
import tempfile
import mido
import pretty_midi
from absl.testing import absltest
from note_seq import constants
from note_seq import midi_io
from note_seq import testing_lib
from note_seq.protobuf import music_pb2

_SIMPLE_MIDI_FILE_NUM_NOTES = 8
_SIMPLE_MIDI_FILE_SUSTAIN = .95

# self.midi_complex_filename contains many instruments including percussion as
# well as control change and pitch bend events.

# self.midi_is_drum_filename contains 41 tracks, two of which are on channel 9.

# self.midi_event_order_filename contains notes ordered
# non-monotonically by pitch.  Here are relevent events as printed by
# mididump.py:
#   midi.NoteOnEvent(tick=0, channel=0, data=[1, 100]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[3, 100]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[2, 100]),
#   midi.NoteOnEvent(tick=4400, channel=0, data=[3, 0]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[1, 0]),
#   midi.NoteOnEvent(tick=0, channel=0, data=[2, 0]),


class MidiIoTest(absltest.TestCase):

  def setUp(self):
    super().setUp()
    self.midi_simple_filename = os.path.join(
        testing_lib.get_testdata_dir(), 'example.mid')
    self.midi_complex_filename = os.path.join(
        testing_lib.get_testdata_dir(), 'example_complex.mid')
    self.midi_is_drum_filename = os.path.join(
        testing_lib.get_testdata_dir(), 'example_is_drum.mid')
    self.midi_event_order_filename = os.path.join(

        testing_lib.get_testdata_dir(), 'example_event_order.mid')