Beispiel #1
0
    def save_midi(self, midi_file_path, onehot_mat, ticksPerQuarterNote=1024):
        """

        :param midi_file_path: path to save midi file which is made after predicting
        :param onehot_mat: matrix having notes infomation made after predicting
        :param ticksPerQuarterNote: criterion of note`s length(duration)
        :return:
        """
        # tick step = 8th note, quaver
        tick_step = ticksPerQuarterNote / 2

        # extract note info from one-hot matrix
        result = []
        for i in range(onehot_mat.shape[0]):
            for j in range(onehot_mat.shape[1]):
                # if flow is started with new note info, then add new info to result list
                if i == 0:
                    if onehot_mat[i, j] == 1:
                        result.append({'time': i * tick_step, 'note': j})
                else:
                    if onehot_mat[i, j] == 1 and onehot_mat[i - 1, j] == 0:
                        result.append({'time': i * tick_step, 'note': j})

        # manufacture result list with unroll package`s Keystrike
        ks = KeyStrikes(result)
        # convert ks to have duration
        ks = ks.quantized(ticksPerQuarterNote)
        # convert ks to music21`s stream
        s = ks._to_music21stream()
        # convert s to midi format, again T^T
        mf = music21.midi.translate.streamToMidiFile(s)
        # save mf info with file
        mf.open(midi_file_path, 'wb')
        mf.write()
        mf.close()

        print '\tMidi file(=%s) successfully saved. Total 1/8 beats = %d' % (
            midi_file_path, onehot_mat.shape[0])
Beispiel #2
0
    def save_midi(self, midi_file_path, onehot_mat, ticksPerQuarterNote=1024):
        """

        :param midi_file_path: predict 후 만들어진 midi file 을 저장할 path
        :param onehot_mat: predict 결과 만들어진 notes 정보를 가진 matrix
        :param ticksPerQuarterNote: note 의 길이 기준
        :return:
        """
        # 틱 간격은 8분의 1음표 단위로
        tick_step = ticksPerQuarterNote / 2

        # onehot matrix에서 note 정보 추출.
        result = []
        for i in range(onehot_mat.shape[0]):
            for j in range(onehot_mat.shape[1]):
                # 새로운 노트가 시작될 경우에 리스트에 추가.
                if i == 0:
                    if onehot_mat[i, j] == 1:
                        result.append({'time': i * tick_step, 'note': j})
                else:
                    if onehot_mat[i, j] == 1 and onehot_mat[i - 1, j] == 0:
                        result.append({'time': i * tick_step, 'note': j})

        # unroll 패키지의 Keystrike를 이용해서 가공.
        ks = KeyStrikes(result)
        # 리스트 형태를 duration 을 가지도록 변환.
        ks = ks.quantized(ticksPerQuarterNote)
        # music21 스트림으로 변환.
        s = ks._to_music21stream()
        # 다시 midi 파일 형식으로 변환. ( ㅠ.ㅠ )
        mf = music21.midi.translate.streamToMidiFile(s)
        # 파일로 저장.
        mf.open(midi_file_path, 'wb')
        mf.write()
        mf.close()

        print '\tMidi file(=%s) successfully saved. Total 1/8 beats = %d' % (midi_file_path, onehot_mat.shape[0])
Beispiel #3
0
    def save_midi(self, midi_file_path, onehot_mat, ticksPerQuarterNote=1024):
        """

        :param midi_file_path: path to save midi file which is made after predicting
        :param onehot_mat: matrix having notes infomation made after predicting
        :param ticksPerQuarterNote: criterion of note`s length(duration)
        :return:
        """
        # tick step = 8th note, quaver
        tick_step = ticksPerQuarterNote / 2

        # extract note info from one-hot matrix
        result = []
        for i in range(onehot_mat.shape[0]):
            for j in range(onehot_mat.shape[1]):
                # if flow is started with new note info, then add new info to result list
                if i == 0:
                    if onehot_mat[i, j] == 1:
                        result.append({'time': i * tick_step, 'note': j})
                else:
                    if onehot_mat[i, j] == 1 and onehot_mat[i - 1, j] == 0:
                        result.append({'time': i * tick_step, 'note': j})

        # manufacture result list with unroll package`s Keystrike
        ks = KeyStrikes(result)
        # convert ks to have duration
        ks = ks.quantized(ticksPerQuarterNote)
        # convert ks to music21`s stream
        s = ks._to_music21stream()
        # convert s to midi format, again T^T
        mf = music21.midi.translate.streamToMidiFile(s)
        # save mf info with file
        mf.open(midi_file_path, 'wb')
        mf.write()
        mf.close()

        print '\tMidi file(=%s) successfully saved. Total 1/8 beats = %d' % (midi_file_path, onehot_mat.shape[0])
Beispiel #4
0
    def load_midi(self, path_data, filename, get_longest_length=False):
        """
        .
        :param path_data: midi files 가 저장되어있는 path
        :param filename: midi file name
        :param get_longest_length: longest play time 을 가진 파일의 길이만 받을지 말지.
        :return:
        """
        # read midi file
        mf = music21.midi.MidiFile()
        path_midifile = path_data + '/' + filename
        mf.open(path_midifile)
        mf.read()
        mf.close()

        # midi -> music21 stream -> midi
        # mf 파일의 ticksperQuarterNote 를 1024 기준으로 바꿔주기
        s = music21.midi.translate.midiFileToStream(mf)
        mf = music21.midi.translate.streamToMidiFile(s)

        #
        # 트랙별 루프 돌면서 note 정보 읽기
        #
        #   트랙별 event 의 구조는 다음과 같다.
        #   <MidiTrack 1 -- 1092 events
        #   <MidiEvent DeltaTime, t=0, track=1, channel=1>
        #   .....
        #   <MidiEvent TIME_SIGNATURE, t=0, track=1, channel=1, data='\x04\x02\x18\x08'>
        #   <MidiEvent DeltaTime, t=0, track=1, channel=1>
        #   <MidiEvent NOTE_ON, t=0, track=1, channel=1, pitch=76, velocity=105>
        #   <MidiEvent DeltaTime, t=512, track=1, channel=1>
        #   <MidiEvent NOTE_OFF, t=0, track=1, channel=1, pitch=76, velocity=0>
        #
        result = []
        for i in range(len(mf.tracks)):
            t = 0
            for e in mf.tracks[i].events:
                if e.isDeltaTime() and e.time is not None:
                    t += e.time
                elif e.isNoteOn() and e.pitch is not None and e.velocity != 0:
                    result.append({'time': t, 'note': e.pitch})

        # unroll.KeyStrikes 이용
        ks = KeyStrikes(result)
        # duration 가지도록 list 변환
        ks = ks.quantized(mf.ticksPerQuarterNote)

        # 가장 sequence 가 긴 파일의 sequence 를 알고 싶을 때
        # get_longest_length = True 로 setting 해주면 가장 긴 sequence 와
        # mf.ticksPerQuarterNote 만 반환.
        if get_longest_length:
            return ks, mf.ticksPerQuarterNote

        #
        # one-hot vector 형식으로 변환
        #

        # tick 간격 = 1/8분 음표 단위로
        self.tick_step = mf.ticksPerQuarterNote / 2
        # 총 틱 카운트
        total_tick = ks.keystrikes[-1]['time'] + ks.keystrikes[-1]['duration'] * mf.ticksPerQuarterNote
        # 총 sequence 갯수
        total_beat = total_tick / self.tick_step

        # 하나의 midi 파일의 one hot vector 를 저장할 임시 matrix
        one_X_train = np.zeros((total_beat + 1, self.data_dim), dtype='int32')

        # 1024 기준으로 convert 된 건반 정보를 루프를 돌면서 디코딩
        for strike in ks.keystrikes:
            # 1/8 음표 단위의 index
            idx = strike['time'] / self.tick_step
            # 1/8 음표 단위 기준 note 의 지속시간 (index 를 몇개 채울거니? 를 계산)
            dur = int(strike['duration'] * 2)

            # note 별로 one-hot vector 채우기
            for note in strike['note']:
                # 지속시간 만큼 making
                for i in range(dur):
                    one_X_train[idx + i, note] = 1

        # 끝에 EOS 추가 = EOS 는 data_dim[-1] = 1 인 경우.
        one_X_train[-1, self.note_dim] = 1

        print '\tMidi file(=%s) successfully loaded. Total 1/8 beats = %d' % (path_midifile, total_beat)

        return one_X_train
Beispiel #5
0
    def load_midi(self, path_data, filename, get_longest_length=False):
        """
        .
        :param path_data: path including midi files
        :param filename: midi file name
        :param get_longest_length: Flag to get only the length of files having longest play time, or not
        :return:
        """
        # read midi file
        mf = music21.midi.MidiFile()
        path_midifile = path_data + '/' + filename
        mf.open(path_midifile)
        mf.read()
        mf.close()

        # midi -> music21 stream -> midi
        # change criterion of ticksperQuarterNote of mf
        s = music21.midi.translate.midiFileToStream(mf)
        mf = music21.midi.translate.streamToMidiFile(s)

        #
        # get notes infomation while loop tracks
        #
        #   track`s event structure
        #   <MidiTrack 1 -- 1092 events
        #   <MidiEvent DeltaTime, t=0, track=1, channel=1>
        #   .....
        #   <MidiEvent TIME_SIGNATURE, t=0, track=1, channel=1, data='\x04\x02\x18\x08'>
        #   <MidiEvent DeltaTime, t=0, track=1, channel=1>
        #   <MidiEvent NOTE_ON, t=0, track=1, channel=1, pitch=76, velocity=105>
        #   <MidiEvent DeltaTime, t=512, track=1, channel=1>
        #   <MidiEvent NOTE_OFF, t=0, track=1, channel=1, pitch=76, velocity=0>
        #
        result = []
        for i in range(len(mf.tracks)):
            t = 0
            for e in mf.tracks[i].events:
                if e.isDeltaTime() and e.time is not None:
                    t += e.time
                elif e.isNoteOn() and e.pitch is not None and e.velocity != 0:
                    result.append({'time': t, 'note': e.pitch})

        # use unroll.KeyStrikes
        ks = KeyStrikes(result)
        # convert list to have duration
        ks = ks.quantized(mf.ticksPerQuarterNote)

        # use If u wanna know the sequence length of file having longest play time,
        # set get_longest_length = True, then this function will return
        # the longest sequence length and mf.ticksPerQuarterNote 만 반환.
        if get_longest_length:
            return ks, mf.ticksPerQuarterNote

        #
        # conver one-hot vector format
        #

        # tick step = 8th note, quaver
        self.tick_step = mf.ticksPerQuarterNote / 2
        # total tick count
        total_tick = ks.keystrikes[-1][
            'time'] + ks.keystrikes[-1]['duration'] * mf.ticksPerQuarterNote
        # total sequence number
        total_beat = total_tick / self.tick_step

        # temporary matrix to save one hot vector of one midi file
        one_X_train = np.zeros((total_beat + 1, self.data_dim), dtype='int32')

        # decoding the notes info while loop with having 1024 criterion
        for strike in ks.keystrikes:
            # index, criterion = 8th note(quaver)
            idx = strike['time'] / self.tick_step
            # during time of note, criterion = 8th note(quaver), calculate how many indices will be filled
            dur = int(strike['duration'] * 2)

            # set one-hot vector by note
            for note in strike['note']:
                # set 1 to index as many as duration of note
                for i in range(dur):
                    one_X_train[idx + i, note] = 1

        # add EOS at end of sequence, EOS is case that data_dim[-1] = 1
        one_X_train[-1, self.note_dim] = 1

        print '\tMidi file(=%s) successfully loaded. Total 1/8 beats = %d' % (
            path_midifile, total_beat)

        return one_X_train
Beispiel #6
0
    def load_midi(self, path_data, filename, get_longest_length=False):
        """
        .
        :param path_data: path including midi files
        :param filename: midi file name
        :param get_longest_length: Flag to get only the length of files having longest play time, or not
        :return:
        """
        # read midi file
        mf = music21.midi.MidiFile()
        path_midifile = path_data + '/' + filename
        mf.open(path_midifile)
        mf.read()
        mf.close()

        # midi -> music21 stream -> midi
        # change criterion of ticksperQuarterNote of mf
        s = music21.midi.translate.midiFileToStream(mf)
        mf = music21.midi.translate.streamToMidiFile(s)

        #
        # get notes infomation while loop tracks
        #
        #   track`s event structure
        #   <MidiTrack 1 -- 1092 events
        #   <MidiEvent DeltaTime, t=0, track=1, channel=1>
        #   .....
        #   <MidiEvent TIME_SIGNATURE, t=0, track=1, channel=1, data='\x04\x02\x18\x08'>
        #   <MidiEvent DeltaTime, t=0, track=1, channel=1>
        #   <MidiEvent NOTE_ON, t=0, track=1, channel=1, pitch=76, velocity=105>
        #   <MidiEvent DeltaTime, t=512, track=1, channel=1>
        #   <MidiEvent NOTE_OFF, t=0, track=1, channel=1, pitch=76, velocity=0>
        #
        result = []
        for i in range(len(mf.tracks)):
            t = 0
            for e in mf.tracks[i].events:
                if e.isDeltaTime() and e.time is not None:
                    t += e.time
                elif e.isNoteOn() and e.pitch is not None and e.velocity != 0:
                    result.append({'time': t, 'note': e.pitch})

        # use unroll.KeyStrikes
        ks = KeyStrikes(result)
        # convert list to have duration
        ks = ks.quantized(mf.ticksPerQuarterNote)

        # use If u wanna know the sequence length of file having longest play time,
        # set get_longest_length = True, then this function will return
        # the longest sequence length and mf.ticksPerQuarterNote 만 반환.
        if get_longest_length:
            return ks, mf.ticksPerQuarterNote

        #
        # conver one-hot vector format
        #

        # tick step = 8th note, quaver
        self.tick_step = mf.ticksPerQuarterNote / 2
        # total tick count
        total_tick = ks.keystrikes[-1]['time'] + ks.keystrikes[-1]['duration'] * mf.ticksPerQuarterNote
        # total sequence number
        total_beat = total_tick / self.tick_step

        # temporary matrix to save one hot vector of one midi file
        one_X_train = np.zeros((total_beat + 1, self.data_dim), dtype='int32')

        # decoding the notes info while loop with having 1024 criterion
        for strike in ks.keystrikes:
            # index, criterion = 8th note(quaver)
            idx = strike['time'] / self.tick_step
            # during time of note, criterion = 8th note(quaver), calculate how many indices will be filled
            dur = int(strike['duration'] * 2)

            # set one-hot vector by note
            for note in strike['note']:
                # set 1 to index as many as duration of note
                for i in range(dur):
                    one_X_train[idx + i, note] = 1

        # add EOS at end of sequence, EOS is case that data_dim[-1] = 1
        one_X_train[-1, self.note_dim] = 1

        print '\tMidi file(=%s) successfully loaded. Total 1/8 beats = %d' % (path_midifile, total_beat)

        return one_X_train