| | import os.path |
| | import json |
| | from tqdm import tqdm |
| | import pandas as pd |
| | import numpy as np |
| | import textgrid |
| | import pretty_midi |
| | import music21 |
| | import librosa |
| | import soundfile as sf |
| |
|
| |
|
| | def piano_roll_to_pretty_midi(piano_roll, fs=100, program=0, bpm=120): |
| | notes, frames = piano_roll.shape |
| | pm = pretty_midi.PrettyMIDI() |
| | instrument = pretty_midi.Instrument(program=program, ) |
| |
|
| | |
| | piano_roll = np.pad(piano_roll, [(0, 0), (1, 1)], 'constant') |
| |
|
| | |
| | velocity_changes = np.nonzero(np.diff(piano_roll).T) |
| |
|
| | |
| | prev_velocities = np.zeros(notes, dtype=int) |
| | note_on_time = np.zeros(notes) |
| |
|
| | for time, note in zip(*velocity_changes): |
| | |
| | velocity = piano_roll[note, time + 1] |
| | time = time / fs * bpm / 120 |
| | |
| | if velocity > 0: |
| | if prev_velocities[note] == 0: |
| | note_on_time[note] = time |
| | prev_velocities[note] = velocity |
| | else: |
| | pm_note = pretty_midi.Note( |
| | velocity=prev_velocities[note], |
| | pitch=note, |
| | start=note_on_time[note], |
| | end=time) |
| | instrument.notes.append(pm_note) |
| | prev_velocities[note] = 0 |
| | pm.instruments.append(instrument) |
| |
|
| | beats = np.array([0, int(pm.get_end_time()+1)]) |
| | pm.adjust_times(beats, beats * 120 / bpm) |
| | |
| | return pm |
| |
|
| |
|
| | f = open('CSD/English/metadata.json', encoding="utf8") |
| | meta = json.load(f) |
| | folder = 'CSD/English/' |
| | for wav in tqdm(os.listdir(folder+'wav')): |
| | song_id = wav.replace('.wav', '') |
| | midi_id = wav.replace('.wav', '.mid') |
| | roll_id = wav.replace('.wav', '.npy') |
| |
|
| | wav, sr = librosa.load(folder+'wav/'+wav) |
| | midi = pretty_midi.PrettyMIDI(folder+'mid/'+midi_id) |
| | roll = midi.get_piano_roll() |
| |
|
| | bpm = meta[song_id]['tempo'] |
| |
|
| | for i in range(int(roll.shape[1])//1000): |
| | |
| | start = i*10 |
| | end = (i+1)*10 |
| |
|
| | wav_seg = wav[round(start * sr):round(end * sr)] |
| |
|
| | os.makedirs('CSD_segements/'+song_id+'/vocal/', exist_ok=True) |
| | os.makedirs('CSD_segements/' + song_id + '/roll/', exist_ok=True) |
| | os.makedirs('CSD_segements/' + song_id + '/midi/', exist_ok=True) |
| |
|
| | sf.write('CSD_segements/'+song_id+'/vocal/'+str(i)+'.wav', wav_seg, samplerate=sr) |
| |
|
| | cur_roll = roll[:, round(100*start):round(100*end)] |
| |
|
| | if round((end-start)*100) != cur_roll.shape[1]: |
| | print(sentence) |
| | print(song_id) |
| | print((end-start)*100) |
| | print(cur_roll.shape) |
| |
|
| | |
| | np.save('CSD_segements/'+song_id+'/roll/'+str(i)+'.npy', cur_roll) |
| |
|
| | |
| | cur_midi = piano_roll_to_pretty_midi(cur_roll, fs=100, bpm=bpm) |
| | |
| | cur_midi.write('CSD_segements/'+song_id+'/midi/'+str(i)+'.midi') |
| | |
| | |
| | |
| | |
| | |