File size: 4,455 Bytes
5288edb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | import pretty_midi
import jsonpickle
def vocal_midi2note(midi):
"""
"""
notes=[]
for note in midi:
pretty_note =pretty_midi.Note(velocity=100, start=note[0], end=note[1], pitch=note[2])
notes.append(pretty_note)
return notes
def quantize(notes, beat_times, downbeat_start, chord_time_gap):
"""
์ด๋ค Note๊ฐ ๋ช๋ฒ์งธ Bar์ ๋ช๋ฒ์งธ timing๋ถํฐ ๋ช๋ฒ์งธ timing๊น์ง ๋ํ๋๋์ง๋ฅผ returnํด์ ์ค๋ค.
Pianoroll์ Index๋ฅผ ๋๊ฒจ์ค๋ค? ๋ผ๊ณ ์๊ฐํ๋ฉด ์ ๋นํ ๋ง๋ค.
ex) 1๋ง๋๊ฐ 1์ด์ธ ๊ณก์์ ์ฐ์ฃผ ์๊ฐ์ด 4.25~4.75์ธ ์์ด ์๊ณ , 1๋ง๋๋ฅผ 48๋ถ ์ํ๊น์ง ๊ณ ๋ คํ๋ค๋ฉด
5๋ฒ์งธ ๋ง๋์ 12~35๊น์ง ์ฐ์ฃผํจ.. ์ด๋ผ๋ ์ ๋ณด๋ฅผ ๊ฑด๋ค์ค
"""
first_beat = downbeat_start
one_beat_time = beat_times[1]-beat_times[0] #๊ทธ๋ฅ 1๋นํธ
quantize_48th_time = one_beat_time/12
beat_num = chord_time_gap//one_beat_time * 12 # 4๋ฐ์ ๊ณก์ด๋ฉด 48, 3๋ฐ์ ๊ณก์ด๋ฉด 36 -> ์ด๊ฑฐ 24๋์ค๋ฉด.. ์๊ฐํ ๋ง๊ฐ์ง๊ฒ ๋ค?
max_idx=0
for note in notes:
start_idx = round((note.start-downbeat_start)/quantize_48th_time)
end_idx = round((note.end-downbeat_start)/quantize_48th_time)
if max_idx <int(start_idx // beat_num):
max_idx = int(start_idx// beat_num)
note_info={str(key) : [] for key in range(max_idx)}
for note in notes:
if note.start>downbeat_start: # ๊ทน์ด๋ฐ์ ์ผ๋ถ ์ํ๊ฐ ์๋ต๋ ์๋ ์๊ธดํฉ๋๋ค.
start_idx = round((note.start-downbeat_start)/quantize_48th_time)
end_idx = round((note.end-downbeat_start)/quantize_48th_time)
if end_idx == start_idx:
end_idx+=1
note_start = start_idx * quantize_48th_time + first_beat
note_end = end_idx * quantize_48th_time + first_beat
note_pitch = note.pitch
note_velocity = note.velocity
bar_idx = int(start_idx // beat_num)
bar_pos = start_idx % beat_num
bar_pos_end = end_idx % beat_num # ์ด๊ฑฐ ๋๋ฌธ์, ์ ๊ธธ์ด๊ฐ ํ ๋ง๋๋ฅผ ๋ชป๋์ด ๊ฐ *** ์๋ฅผ๋ค์ด beatnum์ด 48์ด๊ณ 35~67์ด๋ผ ํ๋ฉด 35 ~ 19 ๋์๋ค๊ฐ if๋ฌธ ํ๋ฉด์ 35~47๋จ.
if bar_pos_end<bar_pos and int(end_idx//beat_num) > bar_idx:
bar_pos_end = (int(end_idx//beat_num) - bar_idx) * beat_num # ์ด์ ๋ ๊ตฌํ ํจ. ๋์ค์ index์๋ฌ ๋ฐ๋์ ๋ ๊ฑฐ์
if bar_pos_end<bar_pos:
bar_pos_end = beat_num-1
note = [float(note_start), float(note_end), int(note_pitch), int(note_velocity), int(bar_pos), int(bar_pos_end)]
#note = {'start':note_start, 'end':note_end, 'pitch':note_pitch, 'velocity':note_velocity, 'start_idx':bar_pos, 'end_idx':bar_pos_end}
if str(bar_idx) not in note_info:
note_info[str(bar_idx)]=[note]
else:
note_info[str(bar_idx)].append(note)
return note_info
def chord_quantize(chord_info, beat_times):
"""
returns Quantized Chord info, First chord starting point and chord time(3๋ฐ์ด๋ 4๋ฐ์ด๋์ ๋ฐ๋ผ chord time์ด ๋ฌ๋ผ์ง๋๋ค. ์ฝ๋ ๋ณํ๊ฐ ํ ๋ง๋ ๋ด์์ ์ฌ๋ฌ๋ฒ ๋์ฌ ์ ์๊ธด ํ์ง๋ง ์ ๋ฐ์ ์ผ๋ก ๋ง๋ ๊ฐ์ฅ ์ฒ์ 1๋ฒ ์ด๋ฃจ์ด์ง๋ค๋ ๊ฐ์ ์ ์ฌ์ฉํฉ๋๋ค.)
first chord๋ ์ฒซ Downbeat์ ์์์ ์๋ฏธํฉ๋๋ค. ๋ค๋ง ๊ณ ์ณ์ผํ ๊ฒ ๊ฐ๋ค์..
"""
first_beat = beat_times[0]
one_beat_time = beat_times[1]-beat_times[0]
q_chord_info = []
for chord in chord_info:
chord_dict={}
chord_dict['chord'] = chord['chord']
chord_dict['start'] = float(round((chord['start']-first_beat)/one_beat_time) * one_beat_time + first_beat) # 0.2, 0.6, 1.0, 1.4 .... ๊ฐ ์๊ณ chord timing์ด 1.9๋ผ๋ฉด 1.8์ returnํ๋ ์ฝ๋
end_time = round((chord['end']-first_beat)/one_beat_time) * one_beat_time + first_beat
if end_time==chord_dict['start']:
end_time += one_beat_time
chord_dict['end'] = float(end_time)
q_chord_info.append(chord_dict)
return q_chord_info
def save_to_json(data, filename):
"""๋ฐ์ดํฐ๋ฅผ JSON ํ์ผ๋ก ์ ์ฅํฉ๋๋ค."""
with open(filename, 'w', encoding='utf-8') as file:
# JSON ํ์์ผ๋ก ๋ณํ
json_data = jsonpickle.encode(data, unpicklable=False)
# ํ์ผ์ ์ฐ๊ธฐ
file.write(json_data)
|