update
Browse files- src/utils/midi.py +66 -9
src/utils/midi.py
CHANGED
|
@@ -243,6 +243,51 @@ def normalize_midi(midi_obj, target_ticks_per_beat=500, target_tempo=120):
|
|
| 243 |
|
| 244 |
return output_midi_obj
|
| 245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
def midi_to_ids(config, midi_obj, normalize=True):
|
| 247 |
def get_pedal(time_list, ccs, time):
|
| 248 |
i = bisect.bisect_right(time_list, time)
|
|
@@ -291,7 +336,7 @@ def midi_to_ids(config, midi_obj, normalize=True):
|
|
| 291 |
ids.extend([pitch, interval, velocity, duration, pedal1, pedal2, pedal3, pedal4])
|
| 292 |
return ids
|
| 293 |
|
| 294 |
-
def ids_to_midi(config, ids, target_ticks_per_beat = 500, target_tempo = 120):
|
| 295 |
note_list = []
|
| 296 |
cc_list = []
|
| 297 |
intervals = []
|
|
@@ -311,14 +356,26 @@ def ids_to_midi(config, ids, target_ticks_per_beat = 500, target_tempo = 120):
|
|
| 311 |
pedal4 = ids[i+7] - config.pedal_start
|
| 312 |
note_list.append(Note(velocity, pitch, last_time + interval, last_time + interval + duration))
|
| 313 |
last_time += interval
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
cc_list.append(ControlChange(64, pedal1, last_time))
|
| 319 |
-
cc_list.append(ControlChange(64, pedal2, round(last_time +
|
| 320 |
-
cc_list.append(ControlChange(64, pedal3, round(last_time +
|
| 321 |
-
cc_list.append(ControlChange(64, pedal4, round(last_time +
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
|
| 323 |
max_tick = 0
|
| 324 |
for note in note_list:
|
|
@@ -328,7 +385,7 @@ def ids_to_midi(config, ids, target_ticks_per_beat = 500, target_tempo = 120):
|
|
| 328 |
max_tick = max_tick + 1
|
| 329 |
|
| 330 |
output = MidiFile(ticks_per_beat=target_ticks_per_beat)
|
| 331 |
-
output.instruments.append(Instrument(program=0, is_drum=False, name="Piano", notes=note_list, control_changes=
|
| 332 |
output.tempo_changes.append(TempoChange(target_tempo, 0))
|
| 333 |
output.max_tick = max_tick
|
| 334 |
|
|
|
|
| 243 |
|
| 244 |
return output_midi_obj
|
| 245 |
|
| 246 |
+
def merge_and_sort(midi_obj):
|
| 247 |
+
output_midi_obj = MidiFile(ticks_per_beat=500)
|
| 248 |
+
output_midi_obj.time_signature_changes = midi_obj.time_signature_changes
|
| 249 |
+
output_midi_obj.key_signature_changes = midi_obj.key_signature_changes
|
| 250 |
+
|
| 251 |
+
output_instrument = Instrument(program=0, is_drum=False, name="Piano")
|
| 252 |
+
tick_ratio = 500 / midi_obj.ticks_per_beat
|
| 253 |
+
all_notes = []
|
| 254 |
+
for instrument in midi_obj.instruments:
|
| 255 |
+
if not instrument.is_drum:
|
| 256 |
+
for note in instrument.notes:
|
| 257 |
+
all_notes.append(
|
| 258 |
+
Note(
|
| 259 |
+
velocity=note.velocity,
|
| 260 |
+
pitch=note.pitch,
|
| 261 |
+
start=round(note.start * tick_ratio),
|
| 262 |
+
end=round(note.end * tick_ratio)
|
| 263 |
+
)
|
| 264 |
+
)
|
| 265 |
+
notes_by_pitch = defaultdict(list)
|
| 266 |
+
for note in all_notes:
|
| 267 |
+
notes_by_pitch[note.pitch].append(note)
|
| 268 |
+
merged_notes = []
|
| 269 |
+
for pitch in sorted(notes_by_pitch.keys()):
|
| 270 |
+
sorted_notes = sorted(notes_by_pitch[pitch], key=lambda n: n.start)
|
| 271 |
+
if len(sorted_notes) > 1:
|
| 272 |
+
for i in range(len(sorted_notes) - 1):
|
| 273 |
+
current_note = sorted_notes[i]
|
| 274 |
+
next_note = sorted_notes[i+1]
|
| 275 |
+
if current_note.end >= next_note.start:
|
| 276 |
+
current_note.end = next_note.start
|
| 277 |
+
if current_note.start >= current_note.end:
|
| 278 |
+
current_note.pitch = -1
|
| 279 |
+
|
| 280 |
+
merged_notes.extend([n for n in sorted_notes if n.pitch != -1])
|
| 281 |
+
|
| 282 |
+
merged_notes.sort(key=lambda x: (x.start, x.pitch))
|
| 283 |
+
output_instrument.notes = merged_notes
|
| 284 |
+
output_midi_obj.instruments.append(output_instrument)
|
| 285 |
+
for time_signature in output_midi_obj.time_signature_changes:
|
| 286 |
+
time_signature.time = round(time_signature.time * tick_ratio)
|
| 287 |
+
for key_signature in output_midi_obj.key_signature_changes:
|
| 288 |
+
key_signature.time = round(key_signature.time * tick_ratio)
|
| 289 |
+
return output_midi_obj
|
| 290 |
+
|
| 291 |
def midi_to_ids(config, midi_obj, normalize=True):
|
| 292 |
def get_pedal(time_list, ccs, time):
|
| 293 |
i = bisect.bisect_right(time_list, time)
|
|
|
|
| 336 |
ids.extend([pitch, interval, velocity, duration, pedal1, pedal2, pedal3, pedal4])
|
| 337 |
return ids
|
| 338 |
|
| 339 |
+
def ids_to_midi(config, ids, target_ticks_per_beat = 500, target_tempo = 120, pedal_ratio = 1.0):
|
| 340 |
note_list = []
|
| 341 |
cc_list = []
|
| 342 |
intervals = []
|
|
|
|
| 356 |
pedal4 = ids[i+7] - config.pedal_start
|
| 357 |
note_list.append(Note(velocity, pitch, last_time + interval, last_time + interval + duration))
|
| 358 |
last_time += interval
|
| 359 |
+
|
| 360 |
+
interval_time = intervals[i // 8 + 1]
|
| 361 |
+
interval_step = intervals[i // 8 + 1] / 4 * pedal_ratio
|
| 362 |
+
|
| 363 |
cc_list.append(ControlChange(64, pedal1, last_time))
|
| 364 |
+
cc_list.append(ControlChange(64, pedal2, round(last_time + interval_step)))
|
| 365 |
+
cc_list.append(ControlChange(64, pedal3, round(last_time + interval_time - interval_step * 2)))
|
| 366 |
+
cc_list.append(ControlChange(64, pedal4, round(last_time + interval_time - interval_step)))
|
| 367 |
+
|
| 368 |
+
#cc_list.append(ControlChange(64, pedal1, last_time))
|
| 369 |
+
#cc_list.append(ControlChange(64, pedal2, round(last_time + intervals[i // 8 + 1] * 1 / 4)))
|
| 370 |
+
#cc_list.append(ControlChange(64, pedal3, round(last_time + intervals[i // 8 + 1] * 2 / 4)))
|
| 371 |
+
#cc_list.append(ControlChange(64, pedal4, round(last_time + intervals[i // 8 + 1] * 3 / 4)))
|
| 372 |
+
|
| 373 |
+
last_value = 0
|
| 374 |
+
new_cc_list = []
|
| 375 |
+
for cc in cc_list:
|
| 376 |
+
if cc.value != last_value:
|
| 377 |
+
new_cc_list.append(cc)
|
| 378 |
+
last_value = cc.value
|
| 379 |
|
| 380 |
max_tick = 0
|
| 381 |
for note in note_list:
|
|
|
|
| 385 |
max_tick = max_tick + 1
|
| 386 |
|
| 387 |
output = MidiFile(ticks_per_beat=target_ticks_per_beat)
|
| 388 |
+
output.instruments.append(Instrument(program=0, is_drum=False, name="Piano", notes=note_list, control_changes=new_cc_list))
|
| 389 |
output.tempo_changes.append(TempoChange(target_tempo, 0))
|
| 390 |
output.max_tick = max_tick
|
| 391 |
|