Exemple #1
0
    def testSimpleSequenceToPrettyMidi_DropEventsAfterLastNote(self):
        source_midi = pretty_midi.PrettyMIDI(self.midi_simple_filename)
        multi_tempo_sequence_proto = midi_io.midi_to_sequence_proto(
            source_midi)
        # Add a final tempo long after the last note.
        multi_tempo_sequence_proto.tempos.add(time=600.0, qpm=120)

        # Translate without dropping.
        translated_midi = midi_io.sequence_proto_to_pretty_midi(
            multi_tempo_sequence_proto)
        self.CheckPrettyMidiAndSequence(translated_midi,
                                        multi_tempo_sequence_proto)

        # Translate dropping anything after the last note.
        translated_midi = midi_io.sequence_proto_to_pretty_midi(
            multi_tempo_sequence_proto,
            drop_events_n_seconds_after_last_note=0)
        # The added tempo should have been dropped.
        del multi_tempo_sequence_proto.tempos[-1]
        self.CheckPrettyMidiAndSequence(translated_midi,
                                        multi_tempo_sequence_proto)

        # Add a final tempo 15 seconds after the last note.
        last_note_time = max(
            [n.end_time for n in multi_tempo_sequence_proto.notes])
        multi_tempo_sequence_proto.tempos.add(time=last_note_time + 15,
                                              qpm=120)
        # Translate dropping anything 30 seconds after the last note, which should
        # preserve the added tempo.
        translated_midi = midi_io.sequence_proto_to_pretty_midi(
            multi_tempo_sequence_proto,
            drop_events_n_seconds_after_last_note=30)
        self.CheckPrettyMidiAndSequence(translated_midi,
                                        multi_tempo_sequence_proto)
def convert_midi(root_dir, sub_dir, full_file_path):
  """Converts a midi file to a sequence proto.

  Args:
    root_dir: A string specifying the root directory for the files being
        converted.
    sub_dir: The directory being converted currently.
    full_file_path: the full path to the file to convert.

  Returns:
    Either a NoteSequence proto or None if the file could not be converted.
  """
  try:
    sequence = midi_io.midi_to_sequence_proto(
        tf.gfile.GFile(full_file_path, 'rb').read())
  except midi_io.MIDIConversionError as e:
    tf.logging.warning(
        'Could not parse MIDI file %s. It will be skipped. Error was: %s',
        full_file_path, e)
    return None
  sequence.collection_name = os.path.basename(root_dir)
  sequence.filename = os.path.join(sub_dir, os.path.basename(full_file_path))
  sequence.id = generate_note_sequence_id(
      sequence.filename, sequence.collection_name, 'midi')
  tf.logging.info('Converted MIDI file %s.', full_file_path)
  return sequence
Exemple #3
0
    def CheckReadWriteMidi(self, filename):
        """Test writing to a MIDI file and comparing it to the original Sequence."""

        # TODO(deck): The input MIDI file is opened in pretty-midi and
        # re-written to a temp file, sanitizing the MIDI data (reordering
        # note ons, etc). Issue 85 in the pretty-midi GitHub
        # (http://github.com/craffel/pretty-midi/issues/85) requests that
        # this sanitization be available outside of the context of a file
        # write. If that is implemented, this rewrite code should be
        # modified or deleted.

        # When writing to the temp file, use the file object itself instead of
        # file.name to avoid the permission error on Windows.
        with tempfile.NamedTemporaryFile(prefix='MidiIoTest') as rewrite_file:
            original_midi = pretty_midi.PrettyMIDI(filename)
            original_midi.write(rewrite_file)  # Use file object
            # Back the file position to top to reload the rewrite_file
            rewrite_file.seek(0)
            source_midi = pretty_midi.PrettyMIDI(
                rewrite_file)  # Use file object
            sequence_proto = midi_io.midi_to_sequence_proto(source_midi)

        # Translate the NoteSequence to MIDI and write to a file.
        with tempfile.NamedTemporaryFile(prefix='MidiIoTest') as temp_file:
            midi_io.sequence_proto_to_midi_file(sequence_proto, temp_file.name)
            # Read it back in and compare to source.
            created_midi = pretty_midi.PrettyMIDI(temp_file)  # Use file object

        self.CheckPrettyMidiAndSequence(created_midi, sequence_proto)
Exemple #4
0
  def testSimpleSequenceToPrettyMidi_MultipleTempos(self):
    source_midi = pretty_midi.PrettyMIDI(self.midi_simple_filename)
    multi_tempo_sequence_proto = midi_io.midi_to_sequence_proto(source_midi)
    multi_tempo_sequence_proto.tempos.add(time=1.0, qpm=60)
    multi_tempo_sequence_proto.tempos.add(time=2.0, qpm=120)

    translated_midi = midi_io.sequence_proto_to_pretty_midi(
        multi_tempo_sequence_proto)

    self.CheckPrettyMidiAndSequence(translated_midi, multi_tempo_sequence_proto)
Exemple #5
0
  def testSimpleSequenceToPrettyMidi_DefaultTicksAndTempo(self):
    source_midi = pretty_midi.PrettyMIDI(self.midi_simple_filename)
    stripped_sequence_proto = midi_io.midi_to_sequence_proto(source_midi)
    del stripped_sequence_proto.tempos[:]
    stripped_sequence_proto.ClearField('ticks_per_quarter')

    expected_sequence_proto = music_pb2.NoteSequence()
    expected_sequence_proto.CopyFrom(stripped_sequence_proto)
    expected_sequence_proto.tempos.add(
        qpm=constants.DEFAULT_QUARTERS_PER_MINUTE)
    expected_sequence_proto.ticks_per_quarter = constants.STANDARD_PPQ

    translated_midi = midi_io.sequence_proto_to_pretty_midi(
        stripped_sequence_proto)

    self.CheckPrettyMidiAndSequence(translated_midi, expected_sequence_proto)
Exemple #6
0
  def testSimpleSequenceToPrettyMidi_FirstTempoNotAtZero(self):
    source_midi = pretty_midi.PrettyMIDI(self.midi_simple_filename)
    multi_tempo_sequence_proto = midi_io.midi_to_sequence_proto(source_midi)
    del multi_tempo_sequence_proto.tempos[:]
    multi_tempo_sequence_proto.tempos.add(time=1.0, qpm=60)
    multi_tempo_sequence_proto.tempos.add(time=2.0, qpm=120)

    translated_midi = midi_io.sequence_proto_to_pretty_midi(
        multi_tempo_sequence_proto)

    # Translating to MIDI adds an implicit DEFAULT_QUARTERS_PER_MINUTE tempo
    # at time 0, so recreate the list with that in place.
    del multi_tempo_sequence_proto.tempos[:]
    multi_tempo_sequence_proto.tempos.add(
        time=0.0, qpm=constants.DEFAULT_QUARTERS_PER_MINUTE)
    multi_tempo_sequence_proto.tempos.add(time=1.0, qpm=60)
    multi_tempo_sequence_proto.tempos.add(time=2.0, qpm=120)

    self.CheckPrettyMidiAndSequence(translated_midi, multi_tempo_sequence_proto)
Exemple #7
0
 def CheckSequenceToPrettyMidi(self, filename):
     """Test the translation from Sequence proto to PrettyMIDI."""
     source_midi = pretty_midi.PrettyMIDI(filename)
     sequence_proto = midi_io.midi_to_sequence_proto(source_midi)
     translated_midi = midi_io.sequence_proto_to_pretty_midi(sequence_proto)
     self.CheckPrettyMidiAndSequence(translated_midi, sequence_proto)
Exemple #8
0
 def CheckMidiToSequence(self, filename):
     """Test the translation from PrettyMIDI to Sequence proto."""
     source_midi = pretty_midi.PrettyMIDI(filename)
     sequence_proto = midi_io.midi_to_sequence_proto(source_midi)
     self.CheckPrettyMidiAndSequence(source_midi, sequence_proto)