yhj137 commited on
Commit
651903a
·
1 Parent(s): 110bcd1
Files changed (1) hide show
  1. 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
- #cc_list.append(ControlChange(64, pedal1, last_time))
315
- #cc_list.append(ControlChange(64, pedal2, round(last_time + min(intervals[i // 8 + 1] * 1 / 10, 5))))
316
- #cc_list.append(ControlChange(64, pedal3, round(last_time + max(intervals[i // 8 + 1] * 8 / 10, intervals[i // 8 + 1] * 8 / 10 - 10))))
317
- #cc_list.append(ControlChange(64, pedal4, round(last_time + max(intervals[i // 8 + 1] * 9 / 10, intervals[i // 8 + 1] * 9 / 10 - 5))))
318
  cc_list.append(ControlChange(64, pedal1, last_time))
319
- cc_list.append(ControlChange(64, pedal2, round(last_time + intervals[i // 8 + 1] * 1 / 4)))
320
- cc_list.append(ControlChange(64, pedal3, round(last_time + intervals[i // 8 + 1] * 2 / 4)))
321
- cc_list.append(ControlChange(64, pedal4, round(last_time + intervals[i // 8 + 1] * 3 / 4)))
 
 
 
 
 
 
 
 
 
 
 
 
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=cc_list))
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