Exemplo n.º 1
0
def part_midi(f, key=None):
    fname = f.split(os.path.sep)[-1]
    _midi = PrettyMIDI(f)
    # part
    for ind, instrument in enumerate(_midi.instruments):
        midi = PrettyMIDI(f)
        n = len(midi.instruments)
        # sound
        for ind2, inst in enumerate(midi.instruments):
            if ind2 != ind:
                inst.program = subSound
            else:
                inst.program = mainSound
        if instrument.name:
            name = instrument.name
        elif len(names) == n:
            name = names[ind]
        else:
            name = str(ind)
        if n != len(volumes):
            continue
        # volume
        for inst, value in zip(midi.instruments, volumes):
            if instrument is inst:
                value += volumeDiff
            inst.control_changes.append(
                ControlChange(number=7, value=value, time=0.001))
        midi.write(
            os.path.join(outdir,
                         fname.rsplit(".", 1)[0] + "_" + name + ".mid"))
Exemplo n.º 2
0
def read_midi_files(path: Union[Path, str],
                    regex: str,
                    extra: bool = True) -> List[Tuple[PrettyMIDI, int]]:
    """
    Reads mid files in given folder and returns a list of PrettyMIDI.
    For all following directories use **/*.*.
    """
    folder = Path(path)
    if extra:
        return [(PrettyMIDI(file.as_posix()), int(file.parent.stem) if
                 file.parent.stem != 'extra' else int(file.parent.parent.stem))
                for file in folder.glob(regex)]
    return [(PrettyMIDI(file.as_posix()), int(file.parent.stem))
            for file in folder.glob(regex) if file.parent.stem != 'extra']
Exemplo n.º 3
0
 def convert2midi(self):
     midi = PrettyMIDI(resolution=STATE_RESOLUTION,
                       initial_tempo=STATE_TEMP)
     inst = Instrument(1, False, 'Note_Seqce')
     inst.notes = copy.deepcopy(self.notes)
     midi.instruments.append(inst)
     return midi
Exemplo n.º 4
0
def create_drum_pretty_midi(
    onset_matrix: np.ndarray,
    vel_matrix: np.ndarray,
    q_note_res: int = Q_NOTE_RES,
    bpm: float = 120.0,
    playback_midi_map: List[int] = CHRISTHETREE_PLAYBACK_MIDI_MAP_8
) -> PrettyMIDI:
    pm = PrettyMIDI(initial_tempo=bpm)

    res = (60.0 / bpm) / q_note_res
    drum_inst = Instrument(0, is_drum=True)
    n_beats = vel_matrix.shape[0]

    for beat_idx in range(n_beats):
        onset_vals = onset_matrix[beat_idx, :]
        onsets = np.nonzero(onset_vals >= 0.5)[0]
        vels = vel_matrix[beat_idx, :]

        for onset in onsets:
            pitch = playback_midi_map[onset]
            vel = int((vels[onset] * 127) + 0.5)
            _add_note(drum_inst, pitch, vel, res * beat_idx,
                      (res * beat_idx) + 0.2)

    pm.instruments.append(drum_inst)
    return pm
def extract_drums(midi_path: str) -> Optional[PrettyMIDI]:
    """
  Extracts a PrettyMIDI instance of all the merged drum tracks
  from the given MIDI path.

  :param midi_path: the path to the MIDI file
  :return: the PrettyMIDI instance of the merged drum tracks
  """
    os.makedirs(args.path_output_dir, exist_ok=True)
    pm = PrettyMIDI(midi_path)
    pm_drums = copy.deepcopy(pm)
    pm_drums.instruments = [
        instrument for instrument in pm_drums.instruments if instrument.is_drum
    ]
    if len(pm_drums.instruments) > 1:
        # Some drum tracks are split, we can merge them
        drums = Instrument(program=0, is_drum=True)
        for instrument in pm_drums.instruments:
            for note in instrument.notes:
                drums.notes.append(note)
        pm_drums.instruments = [drums]
    if len(pm_drums.instruments) != 1:
        raise Exception(f"Invalid number of drums {midi_path}: "
                        f"{len(pm_drums.instruments)}")
    return pm_drums
Exemplo n.º 6
0
def convert_midi_files():
    """Save a multi-track piano-roll converted from a MIDI file to target
    dataset directory and update MIDI information to `midi_dict`"""
    converter_root_dir = 'E:/MIDI_converted'
    root_dir = 'E:/free_MIDI'
    midi_collection = get_midi_collection()
    for midi in midi_collection.find({'Converted': False}):
        genre = midi['Genre']
        name = midi['Name']
        performer = midi['Performer']
        filepath = root_dir + '/' + genre + '/' + name + ' - ' + performer + '.mid'
        try:
            midi_name = os.path.splitext(os.path.basename(filepath))[0]
            multitrack = Multitrack(beat_resolution=24, name=midi_name)

            pm = PrettyMIDI(filepath)
            midi_info = get_midi_info(pm)
            multitrack = Multitrack(filepath)
            merged = get_merged(multitrack)
            os.chdir(converter_root_dir)
            if not os.path.exists(converter_root_dir + '/' + genre):
                os.mkdir(converter_root_dir + '/' + genre)
            converter_path = converter_root_dir + '/' + genre + '/' + midi_name + '.npz'
            # merged.save(converter_path)
            print(get_midi_info(pm))
            '''
            midi_collection.update_one(
                {'_id', midi['_id']},
                {'$set' :{'Converted': True}}
            )
            '''
            # print([midi_name, midi_info])
        except:
            print(filepath)
            print(traceback.format_exc())
Exemplo n.º 7
0
def array_to_pm(array,
                fs=DEFAULT_FS,
                velocity=DEFAULT_VELOCITY,
                pitch_range=DEFAULT_PITCH_RANGE):

    pm = PrettyMIDI()
    inst = Instrument(1)
    pm.instruments.append(inst)

    last_notes = {}
    last_state = np.zeros(array.shape[1]) > 0.5

    for i, step in enumerate(array):
        now = i / fs
        step = step > 0.5
        changed = step != last_state
        for pitch in np.where(changed)[0]:
            if step[pitch]:
                last_notes[pitch] = Note(velocity, pitch + pitch_range.start,
                                         now, None)
                inst.notes.append(last_notes[pitch])
            else:
                last_notes[pitch].end = now
                del last_notes[pitch]
        last_state = step

    now = (i + 1) / fs
    for note in last_notes.values():
        note.end = now

    return pm
Exemplo n.º 8
0
    def to_midi(self, tempo=120, instrument=PIANO, tonic=None, lib=None):
        if not self.progression:
            Logging.error("Progression not assigned!")
            return None
        if not tonic:
            tonic = self.meta['tonic']
        midi = PrettyMIDI()
        unit_length = 30 / tempo
        ins = Instrument(instrument)
        if not self.saved_in_source_base:
            current_pos = 0
            for i in self.get_chord_progression():
                memo = -1
                length = 0
                for j in i:
                    if j == memo:
                        length += unit_length
                    else:
                        if memo != -1:
                            for pitch in memo.to_midi_pitch(
                                    tonic=self.__key_changer(
                                        self.meta['tonic'], memo.root, tonic)):
                                note = Note(pitch=pitch,
                                            velocity=80,
                                            start=current_pos,
                                            end=current_pos + length)
                                ins.notes.append(note)
                        current_pos += length
                        length = unit_length
                        memo = j
                for pitch in memo.to_midi_pitch(tonic=self.__key_changer(
                        self.meta['tonic'], memo.root, tonic)):
                    note = Note(pitch=pitch,
                                velocity=80,
                                start=current_pos,
                                end=current_pos + length)
                    ins.notes.append(note)
                current_pos += length

        else:
            if lib is None:
                lib = pickle_read('lib')
            try:
                all_notes = lib[self.meta['source']]
            except:
                Logging.error(
                    'Progression with source name {n} '
                    'cannot be find in library! '
                    'Call set_in_lib(in_lib=False) to generate MIDI '
                    'by progression list itself'.format(n=self.meta['source']))
                return False
            for note in all_notes:
                ins.notes.append(
                    Note(start=note[0] * unit_length,
                         end=note[1] * unit_length,
                         pitch=note[2] + str_to_root[tonic],
                         velocity=note[3]))

        midi.instruments.append(ins)
        return midi
def extract_drums(msd_id: str) -> Optional[PrettyMIDI]:
  """
  Extracts a PrettyMIDI instance of all the merged drum tracks
  from the given MSD id.

  :param msd_id: the MSD id
  :return: the PrettyMIDI instance of the merged drum tracks
  """
  os.makedirs(args.path_output_dir, exist_ok=True)
  midi_md5 = get_matched_midi_md5(msd_id, MSD_SCORE_MATCHES)
  midi_path = get_midi_path(msd_id, midi_md5, args.path_dataset_dir)
  pm = PrettyMIDI(midi_path)
  pm_drums = copy.deepcopy(pm)
  pm_drums.instruments = [instrument for instrument in pm_drums.instruments
                          if instrument.is_drum]
  if len(pm_drums.instruments) > 1:
    # Some drum tracks are split, we can merge them
    drums = Instrument(program=0, is_drum=True)
    for instrument in pm_drums.instruments:
      for note in instrument.notes:
        drums.notes.append(note)
    pm_drums.instruments = [drums]
  if len(pm_drums.instruments) != 1:
    raise Exception(f"Invalid number of drums {msd_id}: "
                    f"{len(pm_drums.instruments)}")
  return pm_drums
Exemplo n.º 10
0
def listen_pitches(midi_pitch: list, time, instrument=0):
    midi = PrettyMIDI()
    ins = Instrument(instrument)
    for i in midi_pitch:
        ins.notes.append(Note(pitch=i, start=0, end=time, velocity=80))
    midi.instruments.append(ins)
    listen(midi)
Exemplo n.º 11
0
    def write_midi(self,
                   score_events,
                   midi_program,
                   pitch_low_passband=0,
                   pitch_high_passband=127,
                   time_offset=0.0):
        """
        Given a sequence of NoteEvents, calculate the MIDI ticks for each note and write these to a MIDI file.

        PARAMETERS:
            score_events (list): list of ScoreEvents
            midi_program (int): MIDI program to use for the MIDI track
            pitch_low_passband (int): discard any pitches with midi numbers less than this bound
            pitch_high_passband (int): discard any pitches with midi numbers greater than this bound
            time_offset (float): amount of time (s) to delay MIDI note events
        """

        midi = PrettyMIDI(resolution=MidiIO.DEFAULT_PPQ,
                          initial_tempo=MidiIO.DEFAULT_TEMPO)
        instr = Instrument(program=midi_program)
        for e in score_events:
            for n in e.underlying_events():
                if pitch_low_passband <= n.midi_number <= pitch_high_passband:
                    note = MidiNote(velocity=MidiIO.DEFAULT_VELOCITY,
                                    pitch=n.midi_number,
                                    start=(n.onset_ts + time_offset),
                                    end=(n.offset_ts + time_offset))
                    instr.notes.append(note)
        midi.instruments.append(instr)
        midi.remove_invalid_notes()

        directory = os.path.split(self._path)[0]
        if not os.path.exists(directory):
            os.makedirs(directory)
        midi.write(self._path)
Exemplo n.º 12
0
 def to_midi(self, program=DEFAULT_SAVING_PROGRAM,
             resolution=DEFAULT_RESOLUTION, tempo=DEFAULT_TEMPO):
     midi = PrettyMIDI(resolution=resolution, initial_tempo=tempo)
     inst = Instrument(program, False, 'NoteSeq')
     inst.notes = copy.deepcopy(self.notes)
     midi.instruments.append(inst)
     return midi
Exemplo n.º 13
0
def extract_pianos(msd_id: str) -> List[PrettyMIDI]:
    """
  Extracts a list of PrettyMIDI instance of all the separate piano tracks
  from the given MSD id.

  :param msd_id: the MSD id
  :return: the list of PrettyMIDI instances of the separate piano tracks
  """
    os.makedirs(args.path_output_dir, exist_ok=True)
    midi_md5 = get_matched_midi_md5(msd_id, MSD_SCORE_MATCHES)
    midi_path = get_midi_path(msd_id, midi_md5, args.path_dataset_dir)
    pm = PrettyMIDI(midi_path)
    pm.instruments = [
        instrument for instrument in pm.instruments
        if instrument.program in PIANO_PROGRAMS and not instrument.is_drum
    ]
    pm_pianos = []
    if len(pm.instruments) > 1:
        for piano_instrument in pm.instruments:
            pm_piano = copy.deepcopy(pm)
            pm_piano_instrument = Instrument(program=piano_instrument.program)
            pm_piano.instruments = [pm_piano_instrument]
            for note in piano_instrument.notes:
                pm_piano_instrument.notes.append(note)
            pm_pianos.append(pm_piano)
    else:
        pm_pianos.append(pm)
    for index, pm_piano in enumerate(pm_pianos):
        if len(pm_piano.instruments) != 1:
            raise Exception(f"Invalid number of piano {msd_id}: "
                            f"{len(pm_piano.instruments)}")
        if pm_piano.get_end_time() > 1000:
            raise Exception(f"Piano track too long {msd_id}: "
                            f"{pm_piano.get_end_time()}")
    return pm_pianos
Exemplo n.º 14
0
def midi_to_list(filename: str, start_time: float, duration: float) -> List[int]:
    pm = PrettyMIDI(filename)

    pm.adjust_times(np.array([start_time, start_time + duration]), np.array([0., duration]))

    # ensure one midi contain only on instrument
    note_seq = NoteSeq(notes=pm.instruments[0].notes)
    event_seq = EventSeq.from_note_seq(note_seq)
    return event_seq.to_list()
Exemplo n.º 15
0
 def __init__(self, path):
     pm = PrettyMIDI(path)
     pm.remove_invalid_notes()
     self.midi = pm
     self.tempo = pm.estimate_tempo()
     self.beat_times = pm.get_beats()
     self.bar_times = pm.get_downbeats()
     self.end_time = pm.get_end_time()
     self.instruments = pm.instruments
Exemplo n.º 16
0
 def get_midi_file_list(self):
     midi_list = []
     for root, dirs, files in os.walk(self._midi_dir):
         for file in files:
             if fnmatch.fnmatch(file, "*.mid"):
                 midi_filename = os.path.join(root, file)
                 pretty_midi = PrettyMIDI(midi_filename)
                 midi_list.append(pretty_midi)
     return midi_list
Exemplo n.º 17
0
def all_midi(f, key=None):
    midi = PrettyMIDI(f)
    fname = f.split(os.path.sep)[-1]
    n = len(midi.instruments)
    for ind, instrument in enumerate(midi.instruments):
        # sound
        instrument.program = mainSound
        if n == len(volumes):
            instrument.control_changes.append(
                ControlChange(number=7, value=volumes[ind], time=0.001))
    midi.write(os.path.join(outdir, fname.rsplit(".", 1)[0] + "_all.mid"))
Exemplo n.º 18
0
 def __init__(self, midi_path='', phrase=None, meta=None, note_shift=0, **kwargs):
     try:
         self.midi_path = None
         self.note_shift = note_shift
         self.midi = PrettyMIDI(midi_path)
         self.melo = self.midi.instruments[0]
     except:
         self.midi_path = midi_path
         self.melo = self.__load_pop909_melo()
     self.meta = meta
     self.phrase = phrase
Exemplo n.º 19
0
def write_midi(note_sequence, output_dir, filename):

    #make output directory
    pathlib.Path(output_dir).mkdir(parents=True, exist_ok=True)

    #generate midi
    midi = PrettyMIDI()
    piano_track = Instrument(program=0, is_drum=False, name=filename)
    piano_track.notes = note_sequence
    midi.instruments.append(piano_track)
    output_name = output_dir + f"{filename}.midi"
    midi.write(output_name)
Exemplo n.º 20
0
def pitch_lists_to_midi_file(pitch_lists, midi_path):
    midi = PrettyMIDI()
    ins = Instrument(0)
    cursor = 0
    unit_length = 0.125
    for pitch_list in pitch_lists:
        for pitch in pitch_list:
            if pitch != 0:
                ins.notes.append(Note(start=cursor, end=cursor + unit_length, pitch=pitch, velocity=60))
            cursor += unit_length
    midi.instruments.append(ins)
    midi.write(midi_path)
Exemplo n.º 21
0
Arquivo: utils.py Projeto: fuurin/midi
def section(pm, start, end, index=None, exclude_drum=False):
    section_midi = PrettyMIDI()
    for i, instrument in enumerate(pm.instruments):
        if exclude_drum and instrument.is_drum: continue
        if index != None and i not in index: continue
        section_instrument = pretty_midi.Instrument(instrument.program)
        section_instrument.notes = [
            note for note in instrument.notes if start <= note.end < end
        ]
        section_midi.instruments.append(section_instrument)

    return section_midi
Exemplo n.º 22
0
def test_encode_decode():
    mid_seq = MidiSequencer.from_file(PrettyMIDI("audio/rock.mid"))
    encoded = mid_seq.encode()
    decoded = MidiSequencer.decode(encoded)
    for mid_row, decoded_row in zip(mid_seq.pattern, decoded.pattern):
        for mid_note, decoded_note in zip(mid_row, decoded_row):
            if mid_note is None and decoded_note is None:
                assert mid_note is None
                assert decoded_note is None
            else:
                assert mid_note.pitch == decoded_note.pitch
                assert mid_note.start == decoded_note.start
Exemplo n.º 23
0
def read_midi(filename: str, start_time: float, duration: float) -> PrettyMIDI:
    """

    :param filename:
    :param start_time: in seconds
    :param duration: in seconds
    :return:
    """
    pm = PrettyMIDI(filename)

    pm.adjust_times([start_time, start_time + duration], [0., duration])

    return pm
Exemplo n.º 24
0
def convert_midi_to_image(url):
    file = requests.get(url)
    open('input.mid', 'wb').write(file.content)
    pm = PrettyMIDI("input.mid")
    preset = Preset(plot_width=1000, plot_height=500)
    plotter = Plotter(preset=preset)
    plotter.save(pm, 'imageHtml.html')
    hti = Html2Image()
    hti.screenshot(html_file='imageHtml.html',
                   save_as='image.png',
                   size=(1000, 500))
    return discord.File(
        r'image.png') if os.path.getsize('image.png') <= 16000000 else None
Exemplo n.º 25
0
def read_one_midi_and_cut(filename, output, cut_length=16):
    data = PrettyMIDI(filename)
    notes = []
    for track in data.instruments:
        notes += track.notes
    notes = sorted(notes, key=lambda note: note.start)
    #print(notes)
    end_time = 0
    for note in reversed(notes):
        if note.end > end_time:
            end_time = note.end

    start_time = 0
    end_time = max(0, end_time - cut_length)

    import random
    cut_start_time = random.uniform(start_time, end_time)
    cut_end_time = cut_start_time + cut_length

    print('%s: start=%.1f, end=%.1f' %
          (filename, cut_start_time, cut_end_time))

    midi_length = len(notes)
    for i in reversed(range(midi_length)):
        if notes[i].start < cut_start_time or\
                notes[i].start > cut_end_time:
            del notes[i]
        elif notes[i].end > cut_end_time:
            notes[i].end = cut_end_time
    for note in notes:
        note.start -= cut_start_time
        note.end -= cut_start_time

    midi_file = PrettyMIDI(resolution=220, initial_tempo=120)
    track = Instrument(0)
    track.notes = notes
    midi_file.instruments.append(track)
    midi_file.write(output)
def piano_roll2midi(piano_roll, fs=SAMPLE_RATE):

    frames, notes = piano_roll.shape
    pm = PrettyMIDI()
    instrument_program = instrument_name_to_program('Acoustic Grand Piano')
    instrument = Instrument(program=instrument_program)

    piano_roll = np.pad(piano_roll, [(0, 0), (1, 1)], 'constant')
    velocity_changes = np.nonzero(np.diff(piano_roll))

    print(velocity_changes)
    print(*velocity_changes[0])
    print(np.array(velocity_changes).shape)

    prev_velocities = np.zeros(notes, dtype=int)
    note_on_time = np.zeros(notes)
Exemplo n.º 27
0
def read_midi_pretty_midi(path: Union[str, Path]) -> Music:
    """Read a MIDI file into a Music object using pretty_midi as backend.

    Parameters
    ----------
    path : str or Path
        Path to the MIDI file to read.

    Returns
    -------
    :class:`muspy.Music` object
        Converted Music object.

    """
    music = from_pretty_midi(PrettyMIDI(str(path)))
    music.metadata.source_filename = Path(path).name
    return music
Exemplo n.º 28
0
def read(path: Union[str, Path], **kwargs) -> Multitrack:
    """Read a MIDI file into a Multitrack object.

    Parameters
    ----------
    path : str or Path
        Path to the file to read.
    **kwargs
        Keyword arguments to pass to
        :func:`pypianoroll.from_pretty_midi`.

    See Also
    --------
    :func:`pypianoroll.write` : Write a Multitrack object to a MIDI
      file.
    :func:`pypianoroll.load` : Load a NPZ file into a Multitrack object.

    """
    return from_pretty_midi(PrettyMIDI(str(path)), **kwargs)
def get_instrument_classes(msd_id) -> Optional[list]:
    """
  Returns the list of instruments classes given by PrettyMIDI for the MSD id.

  :param msd_id: the MSD id
  :return: the list of instruments classes

  """
    midi_md5 = get_matched_midi_md5(msd_id, MSD_SCORE_MATCHES)
    midi_path = get_midi_path(msd_id, midi_md5, args.path_dataset_dir)
    pm = PrettyMIDI(midi_path)
    classes = [
        program_to_instrument_class(instrument.program)
        for instrument in pm.instruments if not instrument.is_drum
    ]
    drums = ["Drums" for instrument in pm.instruments if instrument.is_drum]
    classes = classes + drums
    if not classes:
        raise Exception(f"No program classes for {msd_id}: " f"{len(classes)}")
    return classes
Exemplo n.º 30
0
 def tokens2midi(self, tokens):
     """
     Игнорирование токенов педали
     :param tokens:
     :return:
     """
     midi = PrettyMIDI()
     program = pretty_midi.instrument_name_to_program('Acoustic Grand Piano')
     piano = Instrument(program=program)
     velocity = 0
     t = 0
     pitch2start = {}
     pitch2end = {}
     pitch2velocity = {}
     for token in tokens:
         if token.startswith("PEDAL"):
             continue
         value = int(token.split("_")[-1])
         if token.startswith("SET_VELOCITY"):
             velocity = value
         if token.startswith("TIME_SHIFT"):
             t += value
             pitch2end = {k: v + value for k, v in pitch2end.items()}
         if token.startswith("NOTE_ON"):
             pitch2start[value] = t
             pitch2end[value] = t
             pitch2velocity[value] = velocity
         if token.startswith("NOTE_OFF"):
             if value in pitch2start:
                 start = pitch2start.pop(value)
                 end = pitch2end.pop(value)
                 if end > start:
                     note = Note(
                         velocity=self._bin2velocity(pitch2velocity.pop(value)),
                         pitch=value,
                         start=start / 1000,
                         end=end / 1000
                     )
                     piano.notes.append(note)
     midi.instruments.append(piano)
     return midi