asigalov61 commited on
Commit
77240fe
1 Parent(s): 4490a32

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +175 -43
TMIDIX.py CHANGED
@@ -174,7 +174,7 @@ Translates a "score" into MIDI, using score2opus() then opus2midi()
174
 
175
  #--------------------------- Decoding stuff ------------------------
176
 
177
- def midi2opus(midi=b''):
178
  r'''Translates MIDI into a "opus". For a description of the
179
  "opus" format, see opus2midi()
180
  '''
@@ -186,7 +186,8 @@ def midi2opus(midi=b''):
186
  if id != b'MThd':
187
  _warn("midi2opus: midi starts with "+str(id)+" instead of 'MThd'")
188
  _clean_up_warnings()
189
- return [1000,[],]
 
190
  [length, format, tracks_expected, ticks] = struct.unpack(
191
  '>IHHH', bytes(my_midi[4:14]))
192
  if length != 6:
@@ -266,27 +267,38 @@ see opus2midi() and score2opus().
266
  _clean_up_warnings()
267
  return score
268
 
269
- def midi2score(midi=b''):
270
  r'''
271
  Translates MIDI into a "score", using midi2opus() then opus2score()
272
  '''
273
- return opus2score(midi2opus(midi))
274
 
275
- def midi2ms_score(midi=b''):
276
  r'''
277
  Translates MIDI into a "score" with one beat per second and one
278
  tick per millisecond, using midi2opus() then to_millisecs()
279
  then opus2score()
280
  '''
281
- return opus2score(to_millisecs(midi2opus(midi)))
282
-
283
- def midi2single_track_ms_score(midi=b'', recalculate_channels = True, pass_old_timings_events= False, verbose = False):
 
 
 
 
 
284
  r'''
285
  Translates MIDI into a single track "score" with 16 instruments and one beat per second and one
286
  tick per millisecond
287
  '''
288
 
289
- score = midi2score(midi)
 
 
 
 
 
 
290
 
291
  if recalculate_channels:
292
 
@@ -1736,7 +1748,9 @@ def plot_ms_SONG(ms_song,
1736
  drums_color_num=128,
1737
  plot_size=(11,4),
1738
  note_height = 0.75,
1739
- show_grid_lines=False):
 
 
1740
 
1741
  '''Tegridy ms SONG plotter/vizualizer'''
1742
 
@@ -1784,15 +1798,16 @@ def plot_ms_SONG(ms_song,
1784
  if show_grid_lines:
1785
  ax.grid(color='white')
1786
 
1787
- plt.xlabel('Time', c='black')
1788
  plt.ylabel('Pitch', c='black')
1789
 
1790
  plt.title(plot_title)
1791
 
1792
- # plt.show()
1793
-
1794
- return plt
1795
-
 
1796
  ###################################################################################
1797
 
1798
  def Tegridy_SONG_to_Full_MIDI_Converter(SONG,
@@ -3782,19 +3797,41 @@ def fix_monophonic_score_durations(monophonic_score):
3782
 
3783
  fixed_score = []
3784
 
3785
- for i in range(len(monophonic_score)-1):
3786
- note = monophonic_score[i]
3787
 
3788
- nmt = monophonic_score[i+1][1]
 
3789
 
3790
- if note[1]+note[2] >= nmt:
3791
- note_dur = nmt-note[1]-1
3792
- else:
3793
- note_dur = note[2]
 
 
 
 
 
 
 
 
 
 
3794
 
3795
- fixed_score.append([note[0], note[1], note_dur, note[3], note[4], note[5]])
 
3796
 
3797
- fixed_score.append(monophonic_score[-1])
 
 
 
 
 
 
 
 
 
 
 
3798
 
3799
  return fixed_score
3800
 
@@ -4058,10 +4095,10 @@ def tones_chord_to_pitches(tones_chord, base_pitch=60):
4058
 
4059
  def advanced_score_processor(raw_score,
4060
  patches_to_analyze=list(range(129)),
4061
- return_score_analysis=True,
4062
  return_enhanced_score=False,
4063
  return_enhanced_score_notes=False,
4064
- return_enhanced_monophonic_melody=False,
4065
  return_chordified_enhanced_score=False,
4066
  return_chordified_enhanced_score_with_lyrics=False,
4067
  return_score_tones_chords=False,
@@ -4329,30 +4366,42 @@ def replace_bad_tones_chord(bad_tones_chord):
4329
  ###################################################################################
4330
 
4331
  def check_and_fix_chord(chord,
4332
- channel_index=3,
4333
- pitch_index=4):
 
4334
 
4335
- chord_notes = [x for x in chord if x[channel_index] != 9]
4336
- chord_drums = [x for x in chord if x[channel_index] == 9]
4337
- chord_pitches = [x[pitch_index] for x in chord_notes]
4338
- tones_chord = sorted(set([x % 12 for x in chord_pitches]))
4339
- good_tones_chord = replace_bad_tones_chord(tones_chord)[0]
4340
- bad_tones = list(set(tones_chord) ^ set(good_tones_chord))
4341
 
4342
- if bad_tones:
 
4343
 
4344
- fixed_chord = []
4345
 
4346
- for c in chord_notes:
4347
- if (c[pitch_index] % 12) not in bad_tones:
4348
- fixed_chord.append(c)
4349
 
4350
- fixed_chord += chord_drums
 
 
4351
 
4352
- return fixed_chord
4353
 
4354
- else:
4355
- return chord
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4356
 
4357
  ###################################################################################
4358
 
@@ -4541,6 +4590,64 @@ def check_and_fix_tones_chord(tones_chord):
4541
 
4542
  ###################################################################################
4543
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4544
  def create_similarity_matrix(list_of_values, matrix_length=0):
4545
 
4546
  counts = Counter(list_of_values).items()
@@ -4564,6 +4671,31 @@ def create_similarity_matrix(list_of_values, matrix_length=0):
4564
 
4565
  ###################################################################################
4566
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4567
  # This is the end of the TMIDI X Python module
4568
 
4569
  ###################################################################################
 
174
 
175
  #--------------------------- Decoding stuff ------------------------
176
 
177
+ def midi2opus(midi=b'', do_not_check_MIDI_signature=False):
178
  r'''Translates MIDI into a "opus". For a description of the
179
  "opus" format, see opus2midi()
180
  '''
 
186
  if id != b'MThd':
187
  _warn("midi2opus: midi starts with "+str(id)+" instead of 'MThd'")
188
  _clean_up_warnings()
189
+ if do_not_check_MIDI_signature == False:
190
+ return [1000,[],]
191
  [length, format, tracks_expected, ticks] = struct.unpack(
192
  '>IHHH', bytes(my_midi[4:14]))
193
  if length != 6:
 
267
  _clean_up_warnings()
268
  return score
269
 
270
+ def midi2score(midi=b'', do_not_check_MIDI_signature=False):
271
  r'''
272
  Translates MIDI into a "score", using midi2opus() then opus2score()
273
  '''
274
+ return opus2score(midi2opus(midi, do_not_check_MIDI_signature))
275
 
276
+ def midi2ms_score(midi=b'', do_not_check_MIDI_signature=False):
277
  r'''
278
  Translates MIDI into a "score" with one beat per second and one
279
  tick per millisecond, using midi2opus() then to_millisecs()
280
  then opus2score()
281
  '''
282
+ return opus2score(to_millisecs(midi2opus(midi, do_not_check_MIDI_signature)))
283
+
284
+ def midi2single_track_ms_score(midi_path_or_bytes,
285
+ recalculate_channels = False,
286
+ pass_old_timings_events= False,
287
+ verbose = False,
288
+ do_not_check_MIDI_signature=False
289
+ ):
290
  r'''
291
  Translates MIDI into a single track "score" with 16 instruments and one beat per second and one
292
  tick per millisecond
293
  '''
294
 
295
+ if type(midi_path_or_bytes) == bytes:
296
+ midi_data = midi_path_or_bytes
297
+
298
+ elif type(midi_path_or_bytes) == str:
299
+ midi_data = open(midi_path_or_bytes, 'rb').read()
300
+
301
+ score = midi2score(midi_data, do_not_check_MIDI_signature)
302
 
303
  if recalculate_channels:
304
 
 
1748
  drums_color_num=128,
1749
  plot_size=(11,4),
1750
  note_height = 0.75,
1751
+ show_grid_lines=False,
1752
+ return_plt = False
1753
+ ):
1754
 
1755
  '''Tegridy ms SONG plotter/vizualizer'''
1756
 
 
1798
  if show_grid_lines:
1799
  ax.grid(color='white')
1800
 
1801
+ plt.xlabel('Time (ms)', c='black')
1802
  plt.ylabel('Pitch', c='black')
1803
 
1804
  plt.title(plot_title)
1805
 
1806
+ if return_plt:
1807
+ return plt
1808
+
1809
+ plt.show()
1810
+
1811
  ###################################################################################
1812
 
1813
  def Tegridy_SONG_to_Full_MIDI_Converter(SONG,
 
3797
 
3798
  fixed_score = []
3799
 
3800
+ if monophonic_score[0][0] == 'note':
 
3801
 
3802
+ for i in range(len(monophonic_score)-1):
3803
+ note = monophonic_score[i]
3804
 
3805
+ nmt = monophonic_score[i+1][1]
3806
+
3807
+ if note[1]+note[2] >= nmt:
3808
+ note_dur = nmt-note[1]-1
3809
+ else:
3810
+ note_dur = note[2]
3811
+
3812
+ new_note = [note[0], note[1], note_dur] + note[3:]
3813
+
3814
+ fixed_score.append(new_note)
3815
+
3816
+ fixed_score.append(monophonic_score[-1])
3817
+
3818
+ elif type(monophonic_score[0][0]) == int:
3819
 
3820
+ for i in range(len(monophonic_score)-1):
3821
+ note = monophonic_score[i]
3822
 
3823
+ nmt = monophonic_score[i+1][0]
3824
+
3825
+ if note[0]+note[1] >= nmt:
3826
+ note_dur = nmt-note[0]-1
3827
+ else:
3828
+ note_dur = note[1]
3829
+
3830
+ new_note = [note[0], note_dur] + note[2:]
3831
+
3832
+ fixed_score.append(new_note)
3833
+
3834
+ fixed_score.append(monophonic_score[-1])
3835
 
3836
  return fixed_score
3837
 
 
4095
 
4096
  def advanced_score_processor(raw_score,
4097
  patches_to_analyze=list(range(129)),
4098
+ return_score_analysis=False,
4099
  return_enhanced_score=False,
4100
  return_enhanced_score_notes=False,
4101
+ return_enhanced_monophonic_melody=False,
4102
  return_chordified_enhanced_score=False,
4103
  return_chordified_enhanced_score_with_lyrics=False,
4104
  return_score_tones_chords=False,
 
4366
  ###################################################################################
4367
 
4368
  def check_and_fix_chord(chord,
4369
+ channel_index=3,
4370
+ pitch_index=4
4371
+ ):
4372
 
4373
+ tones_chord = sorted(set([t[pitch_index] % 12 for t in chord if t[channel_index] != 9]))
 
 
 
 
 
4374
 
4375
+ notes_events = [t for t in chord if t[channel_index] != 9]
4376
+ notes_events.sort(key=lambda x: x[pitch_index], reverse=True)
4377
 
4378
+ drums_events = [t for t in chord if t[channel_index] == 9]
4379
 
4380
+ checked_and_fixed_chord = []
 
 
4381
 
4382
+ if tones_chord:
4383
+
4384
+ new_tones_chord = advanced_check_and_fix_tones_chord(tones_chord, high_pitch=notes_events[0][pitch_index])
4385
 
4386
+ if new_tones_chord != tones_chord:
4387
 
4388
+ if len(notes_events) > 1:
4389
+ checked_and_fixed_chord.extend([notes_events[0]])
4390
+ for cc in notes_events[1:]:
4391
+ if cc[channel_index] != 9:
4392
+ if (cc[pitch_index] % 12) in new_tones_chord:
4393
+ checked_and_fixed_chord.extend([cc])
4394
+ checked_and_fixed_chord.extend(drums_events)
4395
+ else:
4396
+ checked_and_fixed_chord.extend([notes_events[0]])
4397
+ else:
4398
+ checked_and_fixed_chord.extend(chord)
4399
+ else:
4400
+ checked_and_fixed_chord.extend(chord)
4401
+
4402
+ checked_and_fixed_chord.sort(key=lambda x: x[pitch_index], reverse=True)
4403
+
4404
+ return checked_and_fixed_chord
4405
 
4406
  ###################################################################################
4407
 
 
4590
 
4591
  ###################################################################################
4592
 
4593
+ def find_closest_tone(tones, tone):
4594
+ return min(tones, key=lambda x:abs(x-tone))
4595
+
4596
+ def advanced_check_and_fix_tones_chord(tones_chord, high_pitch=0):
4597
+
4598
+ lst = tones_chord
4599
+
4600
+ if 0 < high_pitch < 128:
4601
+ ht = high_pitch % 12
4602
+ else:
4603
+ ht = 12
4604
+
4605
+ cht = find_closest_tone(lst, ht)
4606
+
4607
+ if len(lst) == 2:
4608
+ if lst[1] - lst[0] == 1:
4609
+ return [cht]
4610
+ else:
4611
+ if 0 in lst and 11 in lst:
4612
+ if find_closest_tone([0, 11], cht) == 11:
4613
+ lst.remove(0)
4614
+ else:
4615
+ lst.remove(11)
4616
+ return lst
4617
+
4618
+ non_consecutive = []
4619
+
4620
+ if len(lst) > 2:
4621
+ for i in range(0, len(lst) - 1):
4622
+ if lst[i] + 1 != lst[i+1]:
4623
+ non_consecutive.append(lst[i])
4624
+ if lst[-1] - lst[-2] > 1:
4625
+ non_consecutive.append(lst[-1])
4626
+
4627
+ if cht not in non_consecutive:
4628
+ non_consecutive.append(cht)
4629
+ non_consecutive.sort()
4630
+ if any(abs(non_consecutive[i+1] - non_consecutive[i]) == 1 for i in range(len(non_consecutive) - 1)):
4631
+ final_list = [x for x in non_consecutive if x == cht or abs(x - cht) > 1]
4632
+ else:
4633
+ final_list = non_consecutive
4634
+
4635
+ else:
4636
+ final_list = non_consecutive
4637
+
4638
+ if 0 in final_list and 11 in final_list:
4639
+ if find_closest_tone([0, 11], cht) == 11:
4640
+ final_list.remove(0)
4641
+ else:
4642
+ final_list.remove(11)
4643
+
4644
+ if cht in final_list or ht in final_list:
4645
+ return final_list
4646
+ else:
4647
+ return ['Error']
4648
+
4649
+ ###################################################################################
4650
+
4651
  def create_similarity_matrix(list_of_values, matrix_length=0):
4652
 
4653
  counts = Counter(list_of_values).items()
 
4671
 
4672
  ###################################################################################
4673
 
4674
+ def augment_enhanced_score_notes(enhanced_score_notes,
4675
+ timings_divider=16,
4676
+ full_sorting=True,
4677
+ timings_shift=0,
4678
+ pitch_shift=0
4679
+ ):
4680
+
4681
+ esn = copy.deepcopy(enhanced_score_notes)
4682
+
4683
+ for e in esn:
4684
+ e[1] = int(e[1] / timings_divider) + timings_shift
4685
+ e[2] = int(e[2] / timings_divider) + timings_shift
4686
+ e[4] = e[4] + pitch_shift
4687
+
4688
+ if full_sorting:
4689
+
4690
+ # Sorting by patch, pitch, then by start-time
4691
+ esn.sort(key=lambda x: x[6])
4692
+ esn.sort(key=lambda x: x[4], reverse=True)
4693
+ esn.sort(key=lambda x: x[1])
4694
+
4695
+ return esn
4696
+
4697
+ ###################################################################################
4698
+
4699
  # This is the end of the TMIDI X Python module
4700
 
4701
  ###################################################################################