asigalov61 commited on
Commit
bb620f2
1 Parent(s): bbde7f7

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +1469 -175
TMIDIX.py CHANGED
@@ -1763,7 +1763,10 @@ def plot_ms_SONG(ms_song,
1763
  note_height = 0.75,
1764
  show_grid_lines=False,
1765
  return_plt = False,
1766
- timings_multiplier=1
 
 
 
1767
  ):
1768
 
1769
  '''Tegridy ms SONG plotter/vizualizer'''
@@ -1817,10 +1820,22 @@ def plot_ms_SONG(ms_song,
1817
 
1818
  plt.title(plot_title)
1819
 
 
 
 
 
 
 
 
 
 
 
 
1820
  if return_plt:
1821
  return fig
1822
 
1823
  plt.show()
 
1824
 
1825
  ###################################################################################
1826
 
@@ -1933,7 +1948,7 @@ def Tegridy_Any_Pickle_File_Reader(input_file_name='TMIDI_Pickle_File', ext='.pi
1933
 
1934
  '''Tegridy Pickle File Loader
1935
 
1936
- Input: Full path and file name without extention
1937
  File extension if different from default .pickle
1938
 
1939
  Output: Standard Python 3 unpickled data object
@@ -1945,7 +1960,13 @@ def Tegridy_Any_Pickle_File_Reader(input_file_name='TMIDI_Pickle_File', ext='.pi
1945
  print('Tegridy Pickle File Loader')
1946
  print('Loading the pickle file. Please wait...')
1947
 
1948
- with open(input_file_name + ext, 'rb') as pickle_file:
 
 
 
 
 
 
1949
  content = pickle.load(pickle_file)
1950
 
1951
  if verbose:
@@ -3520,12 +3541,19 @@ def Tegridy_Split_List(list_to_split, split_value=0):
3520
 
3521
  # Binary chords functions
3522
 
3523
- def tones_chord_to_bits(chord):
 
3524
  bits = [0] * 12
 
3525
  for num in chord:
3526
  bits[num] = 1
3527
 
3528
- return bits
 
 
 
 
 
3529
 
3530
  def bits_to_tones_chord(bits):
3531
  return [i for i, bit in enumerate(bits) if bit == 1]
@@ -4582,86 +4610,34 @@ def ascii_text_words_counter(ascii_text):
4582
 
4583
  def check_and_fix_tones_chord(tones_chord):
4584
 
4585
- lst = tones_chord
4586
-
4587
- if len(lst) == 2:
4588
- if lst[1] - lst[0] == 1:
4589
- return [lst[-1]]
4590
- else:
4591
- if 0 in lst and 11 in lst:
4592
- lst.remove(0)
4593
- return lst
4594
-
4595
- non_consecutive = [lst[0]]
4596
-
4597
- if len(lst) > 2:
4598
- for i in range(1, len(lst) - 1):
4599
- if lst[i-1] + 1 != lst[i] and lst[i] + 1 != lst[i+1]:
4600
- non_consecutive.append(lst[i])
4601
- non_consecutive.append(lst[-1])
4602
 
4603
- if 0 in non_consecutive and 11 in non_consecutive:
4604
- non_consecutive.remove(0)
 
 
4605
 
4606
- return non_consecutive
4607
 
4608
  ###################################################################################
4609
 
4610
  def find_closest_tone(tones, tone):
4611
  return min(tones, key=lambda x:abs(x-tone))
4612
 
4613
- def advanced_check_and_fix_tones_chord(tones_chord, high_pitch=0):
4614
-
4615
- lst = tones_chord
4616
-
4617
- if 0 < high_pitch < 128:
4618
- ht = high_pitch % 12
4619
- else:
4620
- ht = 12
4621
 
4622
- cht = find_closest_tone(lst, ht)
4623
 
4624
- if len(lst) == 2:
4625
- if lst[1] - lst[0] == 1:
4626
- return [cht]
4627
- else:
4628
- if 0 in lst and 11 in lst:
4629
- if find_closest_tone([0, 11], cht) == 11:
4630
- lst.remove(0)
4631
- else:
4632
- lst.remove(11)
4633
- return lst
4634
-
4635
- non_consecutive = []
4636
-
4637
- if len(lst) > 2:
4638
- for i in range(0, len(lst) - 1):
4639
- if lst[i] + 1 != lst[i+1]:
4640
- non_consecutive.append(lst[i])
4641
- if lst[-1] - lst[-2] > 1:
4642
- non_consecutive.append(lst[-1])
4643
-
4644
- if cht not in non_consecutive:
4645
- non_consecutive.append(cht)
4646
- non_consecutive.sort()
4647
- if any(abs(non_consecutive[i+1] - non_consecutive[i]) == 1 for i in range(len(non_consecutive) - 1)):
4648
- final_list = [x for x in non_consecutive if x == cht or abs(x - cht) > 1]
4649
- else:
4650
- final_list = non_consecutive
4651
 
4652
- else:
4653
- final_list = non_consecutive
 
4654
 
4655
- if 0 in final_list and 11 in final_list:
4656
- if find_closest_tone([0, 11], cht) == 11:
4657
- final_list.remove(0)
4658
- else:
4659
- final_list.remove(11)
4660
 
4661
- if cht in final_list or ht in final_list:
4662
- return final_list
4663
- else:
4664
- return ['Error']
4665
 
4666
  ###################################################################################
4667
 
@@ -4688,23 +4664,53 @@ def create_similarity_matrix(list_of_values, matrix_length=0):
4688
 
4689
  ###################################################################################
4690
 
 
 
 
 
 
 
4691
  def augment_enhanced_score_notes(enhanced_score_notes,
4692
  timings_divider=16,
4693
  full_sorting=True,
4694
  timings_shift=0,
4695
- pitch_shift=0
 
4696
  ):
4697
 
4698
  esn = copy.deepcopy(enhanced_score_notes)
4699
 
4700
- for e in esn:
4701
- e[1] = int(e[1] / timings_divider) + timings_shift
4702
- e[2] = int(e[2] / timings_divider) + timings_shift
4703
- e[4] = e[4] + pitch_shift
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4704
 
4705
  if full_sorting:
4706
 
4707
- # Sorting by patch, pitch, then by start-time
4708
  esn.sort(key=lambda x: x[6])
4709
  esn.sort(key=lambda x: x[4], reverse=True)
4710
  esn.sort(key=lambda x: x[1])
@@ -4895,25 +4901,26 @@ def patch_list_from_enhanced_score_notes(enhanced_score_notes,
4895
  patches = [-1] * 16
4896
 
4897
  for idx, e in enumerate(enhanced_score_notes):
4898
- if e[3] != 9:
4899
- if patches[e[3]] == -1:
4900
- patches[e[3]] = e[6]
4901
- else:
4902
- if patches[e[3]] != e[6]:
4903
- if e[6] in patches:
4904
- e[3] = patches.index(e[6])
4905
- else:
4906
- if -1 in patches:
4907
- patches[patches.index(-1)] = e[6]
4908
  else:
4909
- patches[-1] = e[6]
 
 
 
4910
 
4911
- if verbose:
4912
- print('=' * 70)
4913
- print('WARNING! Composition has more than 15 patches!')
4914
- print('Conflict note number:', idx)
4915
- print('Conflict channel number:', e[3])
4916
- print('Conflict patch number:', e[6])
4917
 
4918
  patches = [p if p != -1 else default_patch for p in patches]
4919
 
@@ -4946,19 +4953,20 @@ def patch_enhanced_score_notes(enhanced_score_notes,
4946
  overflow_idx = -1
4947
 
4948
  for idx, e in enumerate(enhanced_score_notes):
4949
- if e[3] != 9:
4950
- if patches[e[3]] == -1:
4951
- patches[e[3]] = e[6]
4952
- else:
4953
- if patches[e[3]] != e[6]:
4954
- if e[6] in patches:
4955
- e[3] = patches.index(e[6])
4956
- else:
4957
- if -1 in patches:
4958
- patches[patches.index(-1)] = e[6]
4959
  else:
4960
- overflow_idx = idx
4961
- break
 
 
 
4962
 
4963
  enhanced_score_notes_with_patch_changes.append(e)
4964
 
@@ -4968,15 +4976,16 @@ def patch_enhanced_score_notes(enhanced_score_notes,
4968
 
4969
  if overflow_idx != -1:
4970
  for idx, e in enumerate(enhanced_score_notes[overflow_idx:]):
4971
- if e[3] != 9:
4972
- if e[6] not in patches:
4973
- if e[6] not in overflow_patches:
4974
- overflow_patches.append(e[6])
4975
- enhanced_score_notes_with_patch_changes.append(['patch_change', e[1], e[3], e[6]])
4976
- else:
4977
- e[3] = patches.index(e[6])
 
4978
 
4979
- enhanced_score_notes_with_patch_changes.append(e)
4980
 
4981
  #===========================================================================
4982
 
@@ -5143,7 +5152,8 @@ def advanced_check_and_fix_chords_in_chordified_score(chordified_score,
5143
  channels_index=3,
5144
  pitches_index=4,
5145
  patches_index=6,
5146
- use_filtered_chords=True,
 
5147
  remove_duplicate_pitches=True,
5148
  skip_drums=False
5149
  ):
@@ -5157,6 +5167,9 @@ def advanced_check_and_fix_chords_in_chordified_score(chordified_score,
5157
  else:
5158
  CHORDS = ALL_CHORDS_SORTED
5159
 
 
 
 
5160
  for c in chordified_score:
5161
 
5162
  if remove_duplicate_pitches:
@@ -5259,7 +5272,8 @@ def add_melody_to_enhanced_score_notes(enhanced_score_notes,
5259
  melody_patch=40,
5260
  melody_max_velocity=110,
5261
  acc_max_velocity=90,
5262
- pass_drums=True
 
5263
  ):
5264
 
5265
  if pass_drums:
@@ -5337,7 +5351,11 @@ def add_melody_to_enhanced_score_notes(enhanced_score_notes,
5337
 
5338
  adjust_score_velocities(smoothed_melody, melody_max_velocity)
5339
 
5340
- final_score = sorted(smoothed_melody + acc_score, key=lambda x: (x[1], -x[4]))
 
 
 
 
5341
 
5342
  return final_score
5343
 
@@ -5350,7 +5368,10 @@ def find_paths(list_of_lists, path=[]):
5350
 
5351
  ###################################################################################
5352
 
5353
- def recalculate_score_timings(score, start_time=0):
 
 
 
5354
 
5355
  rscore = copy.deepcopy(score)
5356
 
@@ -5360,10 +5381,10 @@ def recalculate_score_timings(score, start_time=0):
5360
 
5361
  for e in rscore:
5362
 
5363
- dtime = e[1] - pe[1]
5364
  pe = copy.deepcopy(e)
5365
  abs_time += dtime
5366
- e[1] = abs_time
5367
 
5368
  return rscore
5369
 
@@ -5407,11 +5428,11 @@ def harmonize_enhanced_melody_score_notes(enhanced_melody_score_notes):
5407
  cur_chord.append(m)
5408
  cc = sorted(set(cur_chord))
5409
 
5410
- if cc in ALL_CHORDS_FILTERED:
5411
  song.append(cc)
5412
 
5413
  else:
5414
- while sorted(set(cur_chord)) not in ALL_CHORDS_FILTERED:
5415
  cur_chord.pop(0)
5416
  cc = sorted(set(cur_chord))
5417
  song.append(cc)
@@ -5611,7 +5632,8 @@ def basic_enhanced_delta_score_notes_detokenizer(tokenized_seq,
5611
  def enhanced_chord_to_chord_token(enhanced_chord,
5612
  channels_index=3,
5613
  pitches_index=4,
5614
- use_filtered_chords=True
 
5615
  ):
5616
 
5617
  bad_chords_counter = 0
@@ -5622,6 +5644,9 @@ def enhanced_chord_to_chord_token(enhanced_chord,
5622
  else:
5623
  CHORDS = ALL_CHORDS_SORTED
5624
 
 
 
 
5625
  tones_chord = sorted(set([t[pitches_index] % 12 for t in enhanced_chord if t[channels_index] != 9]))
5626
 
5627
  original_tones_chord = copy.deepcopy(tones_chord)
@@ -6360,35 +6385,16 @@ def transpose_pitches(pitches, transpose_value=0):
6360
 
6361
  ###################################################################################
6362
 
6363
- def reverse_enhanced_score_notes(enhanced_score_notes):
6364
-
6365
- score = recalculate_score_timings(enhanced_score_notes)
6366
-
6367
- cscore = chordify_score([1000, score])
6368
-
6369
- abs_dtimes = []
6370
-
6371
- for i, t in enumerate(cscore[:-1]):
6372
- abs_dtimes.append(cscore[i+1][0][1])
6373
- abs_dtimes.append(cscore[-1][0][1]+cscore[-1][0][2])
6374
-
6375
- new_dtimes = []
6376
- pt = abs_dtimes[-1]
6377
 
6378
- for t in abs_dtimes[::-1]:
6379
- new_dtimes.append(abs(pt-t))
6380
- pt = t
6381
 
6382
- new_mel = copy.deepcopy(cscore[::-1])
 
6383
 
6384
- time = 0
6385
-
6386
- for i, t in enumerate(new_mel):
6387
- time += new_dtimes[i]
6388
- for tt in t:
6389
- tt[1] = time
6390
 
6391
- return recalculate_score_timings(flatten(new_mel))
6392
 
6393
  ###################################################################################
6394
 
@@ -6403,6 +6409,8 @@ def count_patterns(lst, sublist):
6403
  idx += 1
6404
  return count
6405
 
 
 
6406
  def find_lrno_patterns(seq):
6407
 
6408
  all_seqs = Counter()
@@ -6689,7 +6697,9 @@ def horizontal_ordered_list_search(list_of_lists,
6689
  ###################################################################################
6690
 
6691
  def escore_notes_to_escore_matrix(escore_notes,
6692
- alt_velocities=False
 
 
6693
  ):
6694
 
6695
  last_time = escore_notes[-1][1]
@@ -6713,7 +6723,7 @@ def escore_notes_to_escore_matrix(escore_notes,
6713
  etype, time, duration, channel, pitch, velocity, patch = note
6714
 
6715
  time = max(0, time)
6716
- duration = max(2, duration)
6717
  channel = max(0, min(15, channel))
6718
  pitch = max(0, min(127, pitch))
6719
  velocity = max(0, min(127, velocity))
@@ -6730,6 +6740,18 @@ def escore_notes_to_escore_matrix(escore_notes,
6730
 
6731
  pe = note
6732
 
 
 
 
 
 
 
 
 
 
 
 
 
6733
  escore_matrixes.append(escore_matrix)
6734
 
6735
  return [channels_list, escore_matrixes]
@@ -6818,7 +6840,9 @@ def escore_matrix_to_original_escore_notes(full_escore_matrix):
6818
 
6819
  def escore_notes_to_binary_matrix(escore_notes,
6820
  channel=0,
6821
- patch=0
 
 
6822
  ):
6823
 
6824
  escore = [e for e in escore_notes if e[3] == channel and e[6] == patch]
@@ -6839,7 +6863,7 @@ def escore_notes_to_binary_matrix(escore_notes,
6839
  etype, time, duration, chan, pitch, velocity, pat = note
6840
 
6841
  time = max(0, time)
6842
- duration = max(2, duration)
6843
  chan = max(0, min(15, chan))
6844
  pitch = max(0, min(127, pitch))
6845
  velocity = max(0, min(127, velocity))
@@ -6851,6 +6875,18 @@ def escore_notes_to_binary_matrix(escore_notes,
6851
 
6852
  escore_matrix[t][pitch] = 1
6853
 
 
 
 
 
 
 
 
 
 
 
 
 
6854
  return escore_matrix
6855
 
6856
  else:
@@ -6861,7 +6897,7 @@ def escore_notes_to_binary_matrix(escore_notes,
6861
  def binary_matrix_to_original_escore_notes(binary_matrix,
6862
  channel=0,
6863
  patch=0,
6864
- velocity=90
6865
  ):
6866
 
6867
  result = []
@@ -6876,20 +6912,34 @@ def binary_matrix_to_original_escore_notes(binary_matrix,
6876
  count += 1
6877
 
6878
  else:
6879
- if count > 1:
 
 
 
 
6880
  result.append([i-count, count, j, binary_matrix[i-1][j]])
6881
 
6882
- count = 1
6883
 
6884
  if count > 1:
6885
  result.append([len(binary_matrix)-count, count, j, binary_matrix[-1][j]])
 
 
 
 
6886
 
6887
  result.sort(key=lambda x: (x[0], -x[2]))
6888
 
6889
  original_escore_notes = []
6890
 
 
 
6891
  for r in result:
6892
- original_escore_notes.append(['note', r[0], r[1], channel, r[2], velocity, patch])
 
 
 
 
6893
 
6894
  return sorted(original_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
6895
 
@@ -7040,7 +7090,8 @@ CHORDS_TYPES = ['WHITE', 'BLACK', 'UNKNOWN', 'MIXED WHITE', 'MIXED BLACK', 'MIXE
7040
 
7041
  def tones_chord_type(tones_chord,
7042
  return_chord_type_index=True,
7043
- use_filtered_chords=True
 
7044
  ):
7045
 
7046
  WN = WHITE_NOTES
@@ -7053,6 +7104,9 @@ def tones_chord_type(tones_chord,
7053
  else:
7054
  CHORDS = ALL_CHORDS_SORTED
7055
 
 
 
 
7056
  tones_chord = sorted(tones_chord)
7057
 
7058
  ctype = 'UNKNOWN'
@@ -7143,7 +7197,8 @@ def find_best_tones_chord(src_tones_chords,
7143
  def find_matching_tones_chords(tones_chord,
7144
  matching_chord_length=-1,
7145
  match_chord_type=True,
7146
- use_filtered_chords=True
 
7147
  ):
7148
 
7149
  if use_filtered_chords:
@@ -7151,6 +7206,9 @@ def find_matching_tones_chords(tones_chord,
7151
  else:
7152
  CHORDS = ALL_CHORDS_SORTED
7153
 
 
 
 
7154
  tones_chord = sorted(tones_chord)
7155
 
7156
  tclen = len(tones_chord)
@@ -7333,7 +7391,8 @@ def harmonize_enhanced_melody_score_notes_to_ms_SONG(escore_notes,
7333
  ###################################################################################
7334
 
7335
  def check_and_fix_pitches_chord(pitches_chord,
7336
- use_filtered_chords=True
 
7337
  ):
7338
 
7339
  pitches_chord = sorted(pitches_chord, reverse=True)
@@ -7343,6 +7402,9 @@ def check_and_fix_pitches_chord(pitches_chord,
7343
  else:
7344
  CHORDS = ALL_CHORDS_SORTED
7345
 
 
 
 
7346
  tones_chord = sorted(set([p % 12 for p in pitches_chord]))
7347
 
7348
  if tones_chord not in CHORDS:
@@ -7361,12 +7423,20 @@ def check_and_fix_pitches_chord(pitches_chord,
7361
  if len(tones_chord) > 2:
7362
 
7363
  tones_chord_combs = [list(comb) for i in range(len(tones_chord)-2, 0, -1) for comb in combinations(tones_chord, i+1)]
 
 
7364
 
7365
  for co in tones_chord_combs:
7366
  if co in CHORDS:
7367
- tones_chord = co
7368
  break
7369
 
 
 
 
 
 
 
7370
  new_pitches_chord = []
7371
 
7372
  for p in pitches_chord:
@@ -7387,7 +7457,7 @@ ALL_CHORDS_TRANS = [[0], [0, 4], [0, 4, 7], [0, 4, 8], [0, 5], [0, 6], [0, 7], [
7387
 
7388
  ###################################################################################
7389
 
7390
- def minkowski_distance(x, y, p=3):
7391
 
7392
  if len(x) != len(y):
7393
  return -1
@@ -7395,36 +7465,1260 @@ def minkowski_distance(x, y, p=3):
7395
  distance = 0
7396
 
7397
  for i in range(len(x)):
 
 
 
 
7398
  distance += abs(x[i] - y[i]) ** p
7399
 
7400
  return distance ** (1 / p)
7401
 
7402
  ###################################################################################
7403
 
7404
- def dot_product(x, y):
7405
- return sum(xi * yi for xi, yi in zip(x, y))
7406
-
7407
- def norm(vector):
7408
- return sum(xi ** 2 for xi in vector) ** 0.5
7409
 
7410
- def cosine_similarity(x, y):
 
7411
 
 
7412
  if len(x) != len(y):
7413
- return -1
7414
-
7415
- dot_prod = dot_product(x, y)
7416
 
7417
- norm_x = norm(x)
7418
- norm_y = norm(y)
 
7419
 
7420
  if norm_x == 0 or norm_y == 0:
7421
  return 0.0
7422
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7423
  else:
7424
- return dot_prod / (norm_x * norm_y)
 
 
 
 
 
 
 
 
 
 
7425
 
7426
  ###################################################################################
7427
 
7428
- # This is the end of the TMIDI X Python module
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7430
  ###################################################################################
 
1763
  note_height = 0.75,
1764
  show_grid_lines=False,
1765
  return_plt = False,
1766
+ timings_multiplier=1,
1767
+ save_plt='',
1768
+ save_only_plt_image=True,
1769
+ save_transparent=False
1770
  ):
1771
 
1772
  '''Tegridy ms SONG plotter/vizualizer'''
 
1820
 
1821
  plt.title(plot_title)
1822
 
1823
+ if save_plt != '':
1824
+ if save_only_plt_image:
1825
+ plt.axis('off')
1826
+ plt.title('')
1827
+ plt.savefig(save_plt, transparent=save_transparent, bbox_inches='tight', pad_inches=0, facecolor='black')
1828
+ plt.close()
1829
+
1830
+ else:
1831
+ plt.savefig(save_plt)
1832
+ plt.close()
1833
+
1834
  if return_plt:
1835
  return fig
1836
 
1837
  plt.show()
1838
+ plt.close()
1839
 
1840
  ###################################################################################
1841
 
 
1948
 
1949
  '''Tegridy Pickle File Loader
1950
 
1951
+ Input: Full path and file name with or without extention
1952
  File extension if different from default .pickle
1953
 
1954
  Output: Standard Python 3 unpickled data object
 
1960
  print('Tegridy Pickle File Loader')
1961
  print('Loading the pickle file. Please wait...')
1962
 
1963
+ if os.path.basename(input_file_name).endswith(ext):
1964
+ fname = input_file_name
1965
+
1966
+ else:
1967
+ fname = input_file_name + ext
1968
+
1969
+ with open(fname, 'rb') as pickle_file:
1970
  content = pickle.load(pickle_file)
1971
 
1972
  if verbose:
 
3541
 
3542
  # Binary chords functions
3543
 
3544
+ def tones_chord_to_bits(chord, reverse=True):
3545
+
3546
  bits = [0] * 12
3547
+
3548
  for num in chord:
3549
  bits[num] = 1
3550
 
3551
+ if reverse:
3552
+ bits.reverse()
3553
+ return bits
3554
+
3555
+ else:
3556
+ return bits
3557
 
3558
  def bits_to_tones_chord(bits):
3559
  return [i for i, bit in enumerate(bits) if bit == 1]
 
4610
 
4611
  def check_and_fix_tones_chord(tones_chord):
4612
 
4613
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord), 0, -1) for comb in combinations(tones_chord, i)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4614
 
4615
+ for c in tones_chord_combs:
4616
+ if c in ALL_CHORDS_FULL:
4617
+ checked_tones_chord = c
4618
+ break
4619
 
4620
+ return sorted(checked_tones_chord)
4621
 
4622
  ###################################################################################
4623
 
4624
  def find_closest_tone(tones, tone):
4625
  return min(tones, key=lambda x:abs(x-tone))
4626
 
4627
+ ###################################################################################
 
 
 
 
 
 
 
4628
 
4629
+ def advanced_check_and_fix_tones_chord(tones_chord, high_pitch=0):
4630
 
4631
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord), 0, -1) for comb in combinations(tones_chord, i)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4632
 
4633
+ for c in tones_chord_combs:
4634
+ if c in ALL_CHORDS_FULL:
4635
+ tchord = c
4636
 
4637
+ if 0 < high_pitch < 128 and len(tchord) == 1:
4638
+ tchord = [high_pitch % 12]
 
 
 
4639
 
4640
+ return tchord
 
 
 
4641
 
4642
  ###################################################################################
4643
 
 
4664
 
4665
  ###################################################################################
4666
 
4667
+ def ceil_with_precision(value, decimal_places):
4668
+ factor = 10 ** decimal_places
4669
+ return math.ceil(value * factor) / factor
4670
+
4671
+ ###################################################################################
4672
+
4673
  def augment_enhanced_score_notes(enhanced_score_notes,
4674
  timings_divider=16,
4675
  full_sorting=True,
4676
  timings_shift=0,
4677
+ pitch_shift=0,
4678
+ legacy_timings=False
4679
  ):
4680
 
4681
  esn = copy.deepcopy(enhanced_score_notes)
4682
 
4683
+ pe = enhanced_score_notes[0]
4684
+
4685
+ abs_time = max(0, int(enhanced_score_notes[0][1] / timings_divider))
4686
+
4687
+ for i, e in enumerate(esn):
4688
+
4689
+ dtime = (e[1] / timings_divider) - (pe[1] / timings_divider)
4690
+
4691
+ if 0.5 < dtime < 1:
4692
+ dtime = 1
4693
+
4694
+ else:
4695
+ dtime = int(dtime)
4696
+
4697
+ if legacy_timings:
4698
+ abs_time = int(e[1] / timings_divider) + timings_shift
4699
+
4700
+ else:
4701
+ abs_time += dtime
4702
+
4703
+ e[1] = max(0, abs_time + timings_shift)
4704
+
4705
+ e[2] = max(1, int(e[2] / timings_divider)) + timings_shift
4706
+
4707
+ e[4] = max(1, min(127, e[4] + pitch_shift))
4708
+
4709
+ pe = enhanced_score_notes[i]
4710
 
4711
  if full_sorting:
4712
 
4713
+ # Sorting by patch, reverse pitch and start-time
4714
  esn.sort(key=lambda x: x[6])
4715
  esn.sort(key=lambda x: x[4], reverse=True)
4716
  esn.sort(key=lambda x: x[1])
 
4901
  patches = [-1] * 16
4902
 
4903
  for idx, e in enumerate(enhanced_score_notes):
4904
+ if e[0] == 'note':
4905
+ if e[3] != 9:
4906
+ if patches[e[3]] == -1:
4907
+ patches[e[3]] = e[6]
4908
+ else:
4909
+ if patches[e[3]] != e[6]:
4910
+ if e[6] in patches:
4911
+ e[3] = patches.index(e[6])
 
 
4912
  else:
4913
+ if -1 in patches:
4914
+ patches[patches.index(-1)] = e[6]
4915
+ else:
4916
+ patches[-1] = e[6]
4917
 
4918
+ if verbose:
4919
+ print('=' * 70)
4920
+ print('WARNING! Composition has more than 15 patches!')
4921
+ print('Conflict note number:', idx)
4922
+ print('Conflict channel number:', e[3])
4923
+ print('Conflict patch number:', e[6])
4924
 
4925
  patches = [p if p != -1 else default_patch for p in patches]
4926
 
 
4953
  overflow_idx = -1
4954
 
4955
  for idx, e in enumerate(enhanced_score_notes):
4956
+ if e[0] == 'note':
4957
+ if e[3] != 9:
4958
+ if patches[e[3]] == -1:
4959
+ patches[e[3]] = e[6]
4960
+ else:
4961
+ if patches[e[3]] != e[6]:
4962
+ if e[6] in patches:
4963
+ e[3] = patches.index(e[6])
 
 
4964
  else:
4965
+ if -1 in patches:
4966
+ patches[patches.index(-1)] = e[6]
4967
+ else:
4968
+ overflow_idx = idx
4969
+ break
4970
 
4971
  enhanced_score_notes_with_patch_changes.append(e)
4972
 
 
4976
 
4977
  if overflow_idx != -1:
4978
  for idx, e in enumerate(enhanced_score_notes[overflow_idx:]):
4979
+ if e[0] == 'note':
4980
+ if e[3] != 9:
4981
+ if e[6] not in patches:
4982
+ if e[6] not in overflow_patches:
4983
+ overflow_patches.append(e[6])
4984
+ enhanced_score_notes_with_patch_changes.append(['patch_change', e[1], e[3], e[6]])
4985
+ else:
4986
+ e[3] = patches.index(e[6])
4987
 
4988
+ enhanced_score_notes_with_patch_changes.append(e)
4989
 
4990
  #===========================================================================
4991
 
 
5152
  channels_index=3,
5153
  pitches_index=4,
5154
  patches_index=6,
5155
+ use_filtered_chords=False,
5156
+ use_full_chords=True,
5157
  remove_duplicate_pitches=True,
5158
  skip_drums=False
5159
  ):
 
5167
  else:
5168
  CHORDS = ALL_CHORDS_SORTED
5169
 
5170
+ if use_full_chords:
5171
+ CHORDS = ALL_CHORDS_FULL
5172
+
5173
  for c in chordified_score:
5174
 
5175
  if remove_duplicate_pitches:
 
5272
  melody_patch=40,
5273
  melody_max_velocity=110,
5274
  acc_max_velocity=90,
5275
+ pass_drums=True,
5276
+ return_melody=False
5277
  ):
5278
 
5279
  if pass_drums:
 
5351
 
5352
  adjust_score_velocities(smoothed_melody, melody_max_velocity)
5353
 
5354
+ if return_melody:
5355
+ final_score = sorted(smoothed_melody, key=lambda x: (x[1], -x[4]))
5356
+
5357
+ else:
5358
+ final_score = sorted(smoothed_melody + acc_score, key=lambda x: (x[1], -x[4]))
5359
 
5360
  return final_score
5361
 
 
5368
 
5369
  ###################################################################################
5370
 
5371
+ def recalculate_score_timings(score,
5372
+ start_time=0,
5373
+ timings_index=1
5374
+ ):
5375
 
5376
  rscore = copy.deepcopy(score)
5377
 
 
5381
 
5382
  for e in rscore:
5383
 
5384
+ dtime = e[timings_index] - pe[timings_index]
5385
  pe = copy.deepcopy(e)
5386
  abs_time += dtime
5387
+ e[timings_index] = abs_time
5388
 
5389
  return rscore
5390
 
 
5428
  cur_chord.append(m)
5429
  cc = sorted(set(cur_chord))
5430
 
5431
+ if cc in ALL_CHORDS_FULL:
5432
  song.append(cc)
5433
 
5434
  else:
5435
+ while sorted(set(cur_chord)) not in ALL_CHORDS_FULL:
5436
  cur_chord.pop(0)
5437
  cc = sorted(set(cur_chord))
5438
  song.append(cc)
 
5632
  def enhanced_chord_to_chord_token(enhanced_chord,
5633
  channels_index=3,
5634
  pitches_index=4,
5635
+ use_filtered_chords=False,
5636
+ use_full_chords=True
5637
  ):
5638
 
5639
  bad_chords_counter = 0
 
5644
  else:
5645
  CHORDS = ALL_CHORDS_SORTED
5646
 
5647
+ if use_full_chords:
5648
+ CHORDS = ALL_CHORDS_FULL
5649
+
5650
  tones_chord = sorted(set([t[pitches_index] % 12 for t in enhanced_chord if t[channels_index] != 9]))
5651
 
5652
  original_tones_chord = copy.deepcopy(tones_chord)
 
6385
 
6386
  ###################################################################################
6387
 
6388
+ def reverse_enhanced_score_notes(escore_notes):
 
 
 
 
 
 
 
 
 
 
 
 
 
6389
 
6390
+ score = recalculate_score_timings(escore_notes)
 
 
6391
 
6392
+ ematrix = escore_notes_to_escore_matrix(score, reverse_matrix=True)
6393
+ e_score = escore_matrix_to_original_escore_notes(ematrix)
6394
 
6395
+ reversed_score = recalculate_score_timings(e_score)
 
 
 
 
 
6396
 
6397
+ return reversed_score
6398
 
6399
  ###################################################################################
6400
 
 
6409
  idx += 1
6410
  return count
6411
 
6412
+ ###################################################################################
6413
+
6414
  def find_lrno_patterns(seq):
6415
 
6416
  all_seqs = Counter()
 
6697
  ###################################################################################
6698
 
6699
  def escore_notes_to_escore_matrix(escore_notes,
6700
+ alt_velocities=False,
6701
+ flip_matrix=False,
6702
+ reverse_matrix=False
6703
  ):
6704
 
6705
  last_time = escore_notes[-1][1]
 
6723
  etype, time, duration, channel, pitch, velocity, patch = note
6724
 
6725
  time = max(0, time)
6726
+ duration = max(1, duration)
6727
  channel = max(0, min(15, channel))
6728
  pitch = max(0, min(127, pitch))
6729
  velocity = max(0, min(127, velocity))
 
6740
 
6741
  pe = note
6742
 
6743
+ if flip_matrix:
6744
+
6745
+ temp_matrix = []
6746
+
6747
+ for m in escore_matrix:
6748
+ temp_matrix.append(m[::-1])
6749
+
6750
+ escore_matrix = temp_matrix
6751
+
6752
+ if reverse_matrix:
6753
+ escore_matrix = escore_matrix[::-1]
6754
+
6755
  escore_matrixes.append(escore_matrix)
6756
 
6757
  return [channels_list, escore_matrixes]
 
6840
 
6841
  def escore_notes_to_binary_matrix(escore_notes,
6842
  channel=0,
6843
+ patch=0,
6844
+ flip_matrix=False,
6845
+ reverse_matrix=False
6846
  ):
6847
 
6848
  escore = [e for e in escore_notes if e[3] == channel and e[6] == patch]
 
6863
  etype, time, duration, chan, pitch, velocity, pat = note
6864
 
6865
  time = max(0, time)
6866
+ duration = max(1, duration)
6867
  chan = max(0, min(15, chan))
6868
  pitch = max(0, min(127, pitch))
6869
  velocity = max(0, min(127, velocity))
 
6875
 
6876
  escore_matrix[t][pitch] = 1
6877
 
6878
+ if flip_matrix:
6879
+
6880
+ temp_matrix = []
6881
+
6882
+ for m in escore_matrix:
6883
+ temp_matrix.append(m[::-1])
6884
+
6885
+ escore_matrix = temp_matrix
6886
+
6887
+ if reverse_matrix:
6888
+ escore_matrix = escore_matrix[::-1]
6889
+
6890
  return escore_matrix
6891
 
6892
  else:
 
6897
  def binary_matrix_to_original_escore_notes(binary_matrix,
6898
  channel=0,
6899
  patch=0,
6900
+ velocity=-1
6901
  ):
6902
 
6903
  result = []
 
6912
  count += 1
6913
 
6914
  else:
6915
+ if count > 1:
6916
+ result.append([i-count, count, j, binary_matrix[i-1][j]])
6917
+
6918
+ else:
6919
+ if binary_matrix[i-1][j] != 0:
6920
  result.append([i-count, count, j, binary_matrix[i-1][j]])
6921
 
6922
+ count = 1
6923
 
6924
  if count > 1:
6925
  result.append([len(binary_matrix)-count, count, j, binary_matrix[-1][j]])
6926
+
6927
+ else:
6928
+ if binary_matrix[i-1][j] != 0:
6929
+ result.append([i-count, count, j, binary_matrix[i-1][j]])
6930
 
6931
  result.sort(key=lambda x: (x[0], -x[2]))
6932
 
6933
  original_escore_notes = []
6934
 
6935
+ vel = velocity
6936
+
6937
  for r in result:
6938
+
6939
+ if velocity == -1:
6940
+ vel = max(40, r[2])
6941
+
6942
+ original_escore_notes.append(['note', r[0], r[1], channel, r[2], vel, patch])
6943
 
6944
  return sorted(original_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
6945
 
 
7090
 
7091
  def tones_chord_type(tones_chord,
7092
  return_chord_type_index=True,
7093
+ use_filtered_chords=False,
7094
+ use_full_chords=True
7095
  ):
7096
 
7097
  WN = WHITE_NOTES
 
7104
  else:
7105
  CHORDS = ALL_CHORDS_SORTED
7106
 
7107
+ if use_full_chords:
7108
+ CHORDS = ALL_CHORDS_FULL
7109
+
7110
  tones_chord = sorted(tones_chord)
7111
 
7112
  ctype = 'UNKNOWN'
 
7197
  def find_matching_tones_chords(tones_chord,
7198
  matching_chord_length=-1,
7199
  match_chord_type=True,
7200
+ use_filtered_chords=True,
7201
+ use_full_chords=True
7202
  ):
7203
 
7204
  if use_filtered_chords:
 
7206
  else:
7207
  CHORDS = ALL_CHORDS_SORTED
7208
 
7209
+ if use_full_chords:
7210
+ CHORDS = ALL_CHORDS_FULL
7211
+
7212
  tones_chord = sorted(tones_chord)
7213
 
7214
  tclen = len(tones_chord)
 
7391
  ###################################################################################
7392
 
7393
  def check_and_fix_pitches_chord(pitches_chord,
7394
+ use_filtered_chords=False,
7395
+ use_full_chords=True
7396
  ):
7397
 
7398
  pitches_chord = sorted(pitches_chord, reverse=True)
 
7402
  else:
7403
  CHORDS = ALL_CHORDS_SORTED
7404
 
7405
+ if use_full_chords:
7406
+ CHORDS = ALL_CHORDS_FULL
7407
+
7408
  tones_chord = sorted(set([p % 12 for p in pitches_chord]))
7409
 
7410
  if tones_chord not in CHORDS:
 
7423
  if len(tones_chord) > 2:
7424
 
7425
  tones_chord_combs = [list(comb) for i in range(len(tones_chord)-2, 0, -1) for comb in combinations(tones_chord, i+1)]
7426
+
7427
+ tchord = []
7428
 
7429
  for co in tones_chord_combs:
7430
  if co in CHORDS:
7431
+ tchord = co
7432
  break
7433
 
7434
+ if tchord:
7435
+ tones_chord = tchord
7436
+
7437
+ else:
7438
+ tones_chord = [pitches_chord[0] % 12]
7439
+
7440
  new_pitches_chord = []
7441
 
7442
  for p in pitches_chord:
 
7457
 
7458
  ###################################################################################
7459
 
7460
+ def minkowski_distance(x, y, p=3, pad_value=float('inf')):
7461
 
7462
  if len(x) != len(y):
7463
  return -1
 
7465
  distance = 0
7466
 
7467
  for i in range(len(x)):
7468
+
7469
+ if x[i] == pad_value or y[i] == pad_value:
7470
+ continue
7471
+
7472
  distance += abs(x[i] - y[i]) ** p
7473
 
7474
  return distance ** (1 / p)
7475
 
7476
  ###################################################################################
7477
 
7478
+ def dot_product(x, y, pad_value=None):
7479
+ return sum(xi * yi for xi, yi in zip(x, y) if xi != pad_value and yi != pad_value)
 
 
 
7480
 
7481
+ def norm(vector, pad_value=None):
7482
+ return sum(xi ** 2 for xi in vector if xi != pad_value) ** 0.5
7483
 
7484
+ def cosine_similarity(x, y, pad_value=None):
7485
  if len(x) != len(y):
7486
+ return -1
 
 
7487
 
7488
+ dot_prod = dot_product(x, y, pad_value)
7489
+ norm_x = norm(x, pad_value)
7490
+ norm_y = norm(y, pad_value)
7491
 
7492
  if norm_x == 0 or norm_y == 0:
7493
  return 0.0
7494
 
7495
+ return dot_prod / (norm_x * norm_y)
7496
+
7497
+ ###################################################################################
7498
+
7499
+ def hamming_distance(arr1, arr2, pad_value):
7500
+ return sum(el1 != el2 for el1, el2 in zip(arr1, arr2) if el1 != pad_value and el2 != pad_value)
7501
+
7502
+ ###################################################################################
7503
+
7504
+ def jaccard_similarity(arr1, arr2, pad_value):
7505
+ intersection = sum(el1 and el2 for el1, el2 in zip(arr1, arr2) if el1 != pad_value and el2 != pad_value)
7506
+ union = sum((el1 or el2) for el1, el2 in zip(arr1, arr2) if el1 != pad_value or el2 != pad_value)
7507
+ return intersection / union if union != 0 else 0
7508
+
7509
+ ###################################################################################
7510
+
7511
+ def pearson_correlation(arr1, arr2, pad_value):
7512
+ filtered_pairs = [(el1, el2) for el1, el2 in zip(arr1, arr2) if el1 != pad_value and el2 != pad_value]
7513
+ if not filtered_pairs:
7514
+ return 0
7515
+ n = len(filtered_pairs)
7516
+ sum1 = sum(el1 for el1, el2 in filtered_pairs)
7517
+ sum2 = sum(el2 for el1, el2 in filtered_pairs)
7518
+ sum1_sq = sum(el1 ** 2 for el1, el2 in filtered_pairs)
7519
+ sum2_sq = sum(el2 ** 2 for el1, el2 in filtered_pairs)
7520
+ p_sum = sum(el1 * el2 for el1, el2 in filtered_pairs)
7521
+ num = p_sum - (sum1 * sum2 / n)
7522
+ den = ((sum1_sq - sum1 ** 2 / n) * (sum2_sq - sum2 ** 2 / n)) ** 0.5
7523
+ if den == 0:
7524
+ return 0
7525
+ return num / den
7526
+
7527
+ ###################################################################################
7528
+
7529
+ def calculate_combined_distances(array_of_arrays,
7530
+ combine_hamming_distance=True,
7531
+ combine_jaccard_similarity=True,
7532
+ combine_pearson_correlation=True,
7533
+ pad_value=None
7534
+ ):
7535
+
7536
+ binary_arrays = array_of_arrays
7537
+ binary_array_len = len(binary_arrays)
7538
+
7539
+ hamming_distances = [[0] * binary_array_len for _ in range(binary_array_len)]
7540
+ jaccard_similarities = [[0] * binary_array_len for _ in range(binary_array_len)]
7541
+ pearson_correlations = [[0] * binary_array_len for _ in range(binary_array_len)]
7542
+
7543
+ for i in range(binary_array_len):
7544
+ for j in range(i + 1, binary_array_len):
7545
+ hamming_distances[i][j] = hamming_distance(binary_arrays[i], binary_arrays[j], pad_value)
7546
+ hamming_distances[j][i] = hamming_distances[i][j]
7547
+
7548
+ jaccard_similarities[i][j] = jaccard_similarity(binary_arrays[i], binary_arrays[j], pad_value)
7549
+ jaccard_similarities[j][i] = jaccard_similarities[i][j]
7550
+
7551
+ pearson_correlations[i][j] = pearson_correlation(binary_arrays[i], binary_arrays[j], pad_value)
7552
+ pearson_correlations[j][i] = pearson_correlations[i][j]
7553
+
7554
+ max_hamming = max(max(row) for row in hamming_distances)
7555
+ min_hamming = min(min(row) for row in hamming_distances)
7556
+ normalized_hamming = [[(val - min_hamming) / (max_hamming - min_hamming) for val in row] for row in hamming_distances]
7557
+
7558
+ max_jaccard = max(max(row) for row in jaccard_similarities)
7559
+ min_jaccard = min(min(row) for row in jaccard_similarities)
7560
+ normalized_jaccard = [[(val - min_jaccard) / (max_jaccard - min_jaccard) for val in row] for row in jaccard_similarities]
7561
+
7562
+ max_pearson = max(max(row) for row in pearson_correlations)
7563
+ min_pearson = min(min(row) for row in pearson_correlations)
7564
+ normalized_pearson = [[(val - min_pearson) / (max_pearson - min_pearson) for val in row] for row in pearson_correlations]
7565
+
7566
+ selected_metrics = 0
7567
+
7568
+ if combine_hamming_distance:
7569
+ selected_metrics += normalized_hamming[i][j]
7570
+
7571
+ if combine_jaccard_similarity:
7572
+ selected_metrics += (1 - normalized_jaccard[i][j])
7573
+
7574
+ if combine_pearson_correlation:
7575
+ selected_metrics += (1 - normalized_pearson[i][j])
7576
+
7577
+ combined_metric = [[selected_metrics for i in range(binary_array_len)] for j in range(binary_array_len)]
7578
+
7579
+ return combined_metric
7580
+
7581
+ ###################################################################################
7582
+
7583
+ def tones_chords_to_bits(tones_chords):
7584
+
7585
+ bits_tones_chords = []
7586
+
7587
+ for c in tones_chords:
7588
+
7589
+ c.sort()
7590
+
7591
+ bits = tones_chord_to_bits(c)
7592
+
7593
+ bits_tones_chords.append(bits)
7594
+
7595
+ return bits_tones_chords
7596
+
7597
+ ###################################################################################
7598
+
7599
+ def tones_chords_to_ints(tones_chords):
7600
+
7601
+ ints_tones_chords = []
7602
+
7603
+ for c in tones_chords:
7604
+
7605
+ c.sort()
7606
+
7607
+ bits = tones_chord_to_bits(c)
7608
+
7609
+ number = bits_to_int(bits)
7610
+
7611
+ ints_tones_chords.append(number)
7612
+
7613
+ return ints_tones_chords
7614
+
7615
+ ###################################################################################
7616
+
7617
+ def tones_chords_to_types(tones_chords,
7618
+ return_chord_type_index=False
7619
+ ):
7620
+
7621
+ types_tones_chords = []
7622
+
7623
+ for c in tones_chords:
7624
+
7625
+ c.sort()
7626
+
7627
+ ctype = tones_chord_type(c, return_chord_type_index=return_chord_type_index)
7628
+
7629
+ types_tones_chords.append(ctype)
7630
+
7631
+ return types_tones_chords
7632
+
7633
+ ###################################################################################
7634
+
7635
+ def morph_tones_chord(tones_chord,
7636
+ trg_tone,
7637
+ use_filtered_chords=True,
7638
+ use_full_chords=True
7639
+ ):
7640
+
7641
+ src_tones_chord = sorted(sorted(set(tones_chord)) + [trg_tone])
7642
+
7643
+ combs = [list(comb) for i in range(len(src_tones_chord), 0, -1) for comb in combinations(src_tones_chord, i) if trg_tone in list(comb)]
7644
+
7645
+ matches = []
7646
+
7647
+ if use_filtered_chords:
7648
+ CHORDS = ALL_CHORDS_FILTERED
7649
+
7650
+ else:
7651
+ CHORDS = ALL_CHORDS_SORTED
7652
+
7653
+ if use_full_chords:
7654
+ CHORDS = ALL_CHORDS_FULL
7655
+
7656
+ for c in combs:
7657
+ if sorted(set(c)) in CHORDS:
7658
+ matches.append(sorted(set(c)))
7659
+
7660
+ max_len = len(max(matches, key=len))
7661
+
7662
+ return random.choice([m for m in matches if len(m) == max_len])
7663
+
7664
+ ###################################################################################
7665
+
7666
+ def compress_binary_matrix(binary_matrix,
7667
+ only_compress_zeros=False,
7668
+ return_compression_ratio=False
7669
+ ):
7670
+
7671
+ compressed_bmatrix = []
7672
+
7673
+ zm = [0] * len(binary_matrix[0])
7674
+ pm = [0] * len(binary_matrix[0])
7675
+
7676
+ mcount = 0
7677
+
7678
+ for m in binary_matrix:
7679
+
7680
+ if only_compress_zeros:
7681
+ if m != zm:
7682
+ compressed_bmatrix.append(m)
7683
+ mcount += 1
7684
+
7685
  else:
7686
+ if m != pm:
7687
+ compressed_bmatrix.append(m)
7688
+ mcount += 1
7689
+
7690
+ pm = m
7691
+
7692
+ if return_compression_ratio:
7693
+ return [compressed_bmatrix, mcount / len(binary_matrix)]
7694
+
7695
+ else:
7696
+ return compressed_bmatrix
7697
 
7698
  ###################################################################################
7699
 
7700
+ def solo_piano_escore_notes(escore_notes,
7701
+ channels_index=3,
7702
+ pitches_index=4,
7703
+ patches_index=6,
7704
+ keep_drums=False,
7705
+ ):
7706
+
7707
+ cscore = chordify_score([1000, escore_notes])
7708
+
7709
+ sp_escore_notes = []
7710
+
7711
+ for c in cscore:
7712
+
7713
+ seen = []
7714
+ chord = []
7715
+
7716
+ for cc in c:
7717
+ if cc[pitches_index] not in seen:
7718
+
7719
+ if cc[channels_index] != 9:
7720
+ cc[channels_index] = 0
7721
+ cc[patches_index] = 0
7722
+
7723
+ chord.append(cc)
7724
+ seen.append(cc[pitches_index])
7725
+
7726
+ else:
7727
+ if keep_drums:
7728
+ chord.append(cc)
7729
+ seen.append(cc[pitches_index])
7730
+
7731
+ sp_escore_notes.append(chord)
7732
+
7733
+ return flatten(sp_escore_notes)
7734
+
7735
+ ###################################################################################
7736
 
7737
+ def strip_drums_from_escore_notes(escore_notes,
7738
+ channels_index=3
7739
+ ):
7740
+
7741
+ return [e for e in escore_notes if e[channels_index] != 9]
7742
+
7743
+ ###################################################################################
7744
+
7745
+ def fixed_escore_notes_timings(escore_notes,
7746
+ fixed_durations=False,
7747
+ fixed_timings_multiplier=1,
7748
+ custom_fixed_time=-1,
7749
+ custom_fixed_dur=-1
7750
+ ):
7751
+
7752
+ fixed_timings_escore_notes = delta_score_notes(escore_notes, even_timings=True)
7753
+
7754
+ mode_time = round(Counter([e[1] for e in fixed_timings_escore_notes if e[1] != 0]).most_common()[0][0] * fixed_timings_multiplier)
7755
+
7756
+ if mode_time % 2 != 0:
7757
+ mode_time += 1
7758
+
7759
+ mode_dur = round(Counter([e[2] for e in fixed_timings_escore_notes if e[2] != 0]).most_common()[0][0] * fixed_timings_multiplier)
7760
+
7761
+ if mode_dur % 2 != 0:
7762
+ mode_dur += 1
7763
+
7764
+ for e in fixed_timings_escore_notes:
7765
+ if e[1] != 0:
7766
+
7767
+ if custom_fixed_time > 0:
7768
+ e[1] = custom_fixed_time
7769
+
7770
+ else:
7771
+ e[1] = mode_time
7772
+
7773
+ if fixed_durations:
7774
+
7775
+ if custom_fixed_dur > 0:
7776
+ e[2] = custom_fixed_dur
7777
+
7778
+ else:
7779
+ e[2] = mode_dur
7780
+
7781
+ return delta_score_to_abs_score(fixed_timings_escore_notes)
7782
+
7783
+ ###################################################################################
7784
+
7785
+ def cubic_kernel(x):
7786
+ abs_x = abs(x)
7787
+ if abs_x <= 1:
7788
+ return 1.5 * abs_x**3 - 2.5 * abs_x**2 + 1
7789
+ elif abs_x <= 2:
7790
+ return -0.5 * abs_x**3 + 2.5 * abs_x**2 - 4 * abs_x + 2
7791
+ else:
7792
+ return 0
7793
+
7794
+ ###################################################################################
7795
+
7796
+ def resize_matrix(matrix, new_height, new_width):
7797
+ old_height = len(matrix)
7798
+ old_width = len(matrix[0])
7799
+ resized_matrix = [[0] * new_width for _ in range(new_height)]
7800
+
7801
+ for i in range(new_height):
7802
+ for j in range(new_width):
7803
+ old_i = i * old_height / new_height
7804
+ old_j = j * old_width / new_width
7805
+
7806
+ value = 0
7807
+ total_weight = 0
7808
+ for m in range(-1, 3):
7809
+ for n in range(-1, 3):
7810
+ i_m = min(max(int(old_i) + m, 0), old_height - 1)
7811
+ j_n = min(max(int(old_j) + n, 0), old_width - 1)
7812
+
7813
+ if matrix[i_m][j_n] == 0:
7814
+ continue
7815
+
7816
+ weight = cubic_kernel(old_i - i_m) * cubic_kernel(old_j - j_n)
7817
+ value += matrix[i_m][j_n] * weight
7818
+ total_weight += weight
7819
+
7820
+ if total_weight > 0:
7821
+ value /= total_weight
7822
+
7823
+ resized_matrix[i][j] = int(value > 0.5)
7824
+
7825
+ return resized_matrix
7826
+
7827
+ ###################################################################################
7828
+
7829
+ def square_binary_matrix(binary_matrix,
7830
+ matrix_size=128,
7831
+ use_fast_squaring=False,
7832
+ return_plot_points=False
7833
+ ):
7834
+
7835
+ if use_fast_squaring:
7836
+
7837
+ step = round(len(binary_matrix) / matrix_size)
7838
+
7839
+ samples = []
7840
+
7841
+ for i in range(0, len(binary_matrix), step):
7842
+ samples.append(tuple([tuple(d) for d in binary_matrix[i:i+step]]))
7843
+
7844
+ resized_matrix = []
7845
+
7846
+ zmatrix = [[0] * matrix_size]
7847
+
7848
+ for s in samples:
7849
+
7850
+ samples_counts = Counter(s).most_common()
7851
+
7852
+ best_sample = tuple([0] * matrix_size)
7853
+ pm = tuple(zmatrix[0])
7854
+
7855
+ for sc in samples_counts:
7856
+ if sc[0] != tuple(zmatrix[0]) and sc[0] != pm:
7857
+ best_sample = sc[0]
7858
+ pm = sc[0]
7859
+ break
7860
+
7861
+ pm = sc[0]
7862
+
7863
+ resized_matrix.append(list(best_sample))
7864
+
7865
+ resized_matrix = resized_matrix[:matrix_size]
7866
+ resized_matrix += zmatrix * (matrix_size - len(resized_matrix))
7867
+
7868
+ else:
7869
+ resized_matrix = resize_matrix(binary_matrix, matrix_size, matrix_size)
7870
+
7871
+ points = [(i, j) for i in range(matrix_size) for j in range(matrix_size) if resized_matrix[i][j] == 1]
7872
+
7873
+ if return_plot_points:
7874
+ return [resized_matrix, points]
7875
+
7876
+ else:
7877
+ return resized_matrix
7878
+
7879
+ ###################################################################################
7880
+
7881
+ def mean(matrix):
7882
+ return sum(sum(row) for row in matrix) / (len(matrix) * len(matrix[0]))
7883
+
7884
+ ###################################################################################
7885
+
7886
+ def variance(matrix, mean_value):
7887
+ return sum(sum((element - mean_value) ** 2 for element in row) for row in matrix) / (len(matrix) * len(matrix[0]))
7888
+
7889
+ ###################################################################################
7890
+
7891
+ def covariance(matrix1, matrix2, mean1, mean2):
7892
+ return sum(sum((matrix1[i][j] - mean1) * (matrix2[i][j] - mean2) for j in range(len(matrix1[0]))) for i in range(len(matrix1))) / (len(matrix1) * len(matrix1[0]))
7893
+
7894
+ ###################################################################################
7895
+
7896
+ def ssim_index(matrix1, matrix2, bit_depth=1):
7897
+
7898
+ if len(matrix1) != len(matrix2) and len(matrix1[0]) != len(matrix2[0]):
7899
+ return -1
7900
+
7901
+ K1, K2 = 0.01, 0.03
7902
+ L = bit_depth
7903
+ C1 = (K1 * L) ** 2
7904
+ C2 = (K2 * L) ** 2
7905
+
7906
+ mu1 = mean(matrix1)
7907
+ mu2 = mean(matrix2)
7908
+
7909
+ sigma1_sq = variance(matrix1, mu1)
7910
+ sigma2_sq = variance(matrix2, mu2)
7911
+
7912
+ sigma12 = covariance(matrix1, matrix2, mu1, mu2)
7913
+
7914
+ ssim = ((2 * mu1 * mu2 + C1) * (2 * sigma12 + C2)) / ((mu1 ** 2 + mu2 ** 2 + C1) * (sigma1_sq + sigma2_sq + C2))
7915
+
7916
+ return ssim
7917
+
7918
+ ###################################################################################
7919
+
7920
+ def find_most_similar_matrix(array_of_matrices,
7921
+ trg_matrix,
7922
+ matrices_bit_depth=1,
7923
+ return_most_similar_index=False
7924
+ ):
7925
+
7926
+ max_ssim = -float('inf')
7927
+ most_similar_index = -1
7928
+
7929
+ for i, matrix in enumerate(array_of_matrices):
7930
+
7931
+ ssim = ssim_index(matrix, trg_matrix, bit_depth=matrices_bit_depth)
7932
+
7933
+ if ssim > max_ssim:
7934
+ max_ssim = ssim
7935
+ most_similar_index = i
7936
+
7937
+ if return_most_similar_index:
7938
+ return most_similar_index
7939
+
7940
+ else:
7941
+ return array_of_matrices[most_similar_index]
7942
+
7943
+ ###################################################################################
7944
+
7945
+ def chord_to_pchord(chord):
7946
+
7947
+ pchord = []
7948
+
7949
+ for cc in chord:
7950
+ if cc[3] != 9:
7951
+ pchord.append(cc[4])
7952
+
7953
+ return pchord
7954
+
7955
+ ###################################################################################
7956
+
7957
+ def summarize_escore_notes(escore_notes,
7958
+ summary_length_in_chords=128,
7959
+ preserve_timings=True,
7960
+ preserve_durations=False,
7961
+ time_threshold=12,
7962
+ min_sum_chord_len=2,
7963
+ use_tones_chords=True
7964
+ ):
7965
+
7966
+ cscore = chordify_score([d[1:] for d in delta_score_notes(escore_notes)])
7967
+
7968
+ summary_length_in_chords = min(len(cscore), summary_length_in_chords)
7969
+
7970
+ ltthresh = time_threshold // 2
7971
+ uttresh = time_threshold * 2
7972
+
7973
+ mc_time = Counter([c[0][0] for c in cscore if c[0][2] != 9 and ltthresh < c[0][0] < uttresh]).most_common()[0][0]
7974
+
7975
+ pchords = []
7976
+
7977
+ for c in cscore:
7978
+ if use_tones_chords:
7979
+ pchords.append([c[0][0]] + pitches_to_tones_chord(chord_to_pchord(c)))
7980
+
7981
+ else:
7982
+ pchords.append([c[0][0]] + chord_to_pchord(c))
7983
+
7984
+ step = round(len(pchords) / summary_length_in_chords)
7985
+
7986
+ samples = []
7987
+
7988
+ for i in range(0, len(pchords), step):
7989
+ samples.append(tuple([tuple(d) for d in pchords[i:i+step]]))
7990
+
7991
+ summarized_escore_notes = []
7992
+
7993
+ for i, s in enumerate(samples):
7994
+
7995
+ best_chord = list([v[0] for v in Counter(s).most_common() if v[0][0] == mc_time and len(v[0]) > min_sum_chord_len])
7996
+
7997
+ if not best_chord:
7998
+ best_chord = list([v[0] for v in Counter(s).most_common() if len(v[0]) > min_sum_chord_len])
7999
+
8000
+ if not best_chord:
8001
+ best_chord = list([Counter(s).most_common()[0][0]])
8002
+
8003
+ chord = copy.deepcopy(cscore[[ss for ss in s].index(best_chord[0])+(i*step)])
8004
+
8005
+ if preserve_timings:
8006
+
8007
+ if not preserve_durations:
8008
+
8009
+ if i > 0:
8010
+
8011
+ pchord = summarized_escore_notes[-1]
8012
+
8013
+ for pc in pchord:
8014
+ pc[1] = min(pc[1], chord[0][0])
8015
+
8016
+ else:
8017
+
8018
+ chord[0][0] = 1
8019
+
8020
+ for c in chord:
8021
+ c[1] = 1
8022
+
8023
+ summarized_escore_notes.append(chord)
8024
+
8025
+ summarized_escore_notes = summarized_escore_notes[:summary_length_in_chords]
8026
+
8027
+ return [['note'] + d for d in delta_score_to_abs_score(flatten(summarized_escore_notes), times_idx=0)]
8028
+
8029
+ ###################################################################################
8030
+
8031
+ def compress_patches_in_escore_notes(escore_notes,
8032
+ num_patches=4,
8033
+ group_patches=False
8034
+ ):
8035
+
8036
+ if num_patches > 4:
8037
+ n_patches = 4
8038
+ elif num_patches < 1:
8039
+ n_patches = 1
8040
+ else:
8041
+ n_patches = num_patches
8042
+
8043
+ if group_patches:
8044
+ patches_set = sorted(set([e[6] for e in c]))
8045
+ trg_patch_list = []
8046
+ seen = []
8047
+ for p in patches_set:
8048
+ if p // 8 not in seen:
8049
+ trg_patch_list.append(p)
8050
+ seen.append(p // 8)
8051
+
8052
+ trg_patch_list = sorted(trg_patch_list)
8053
+
8054
+ else:
8055
+ trg_patch_list = sorted(set([e[6] for e in c]))
8056
+
8057
+ if 128 in trg_patch_list and n_patches > 1:
8058
+ trg_patch_list = trg_patch_list[:n_patches-1] + [128]
8059
+ else:
8060
+ trg_patch_list = trg_patch_list[:n_patches]
8061
+
8062
+ new_escore_notes = []
8063
+
8064
+ for e in escore_notes:
8065
+ if e[6] in trg_patch_list:
8066
+ new_escore_notes.append(e)
8067
+
8068
+ return new_escore_notes
8069
+
8070
+ ###################################################################################
8071
+
8072
+ def compress_patches_in_escore_notes_chords(escore_notes,
8073
+ max_num_patches_per_chord=4,
8074
+ group_patches=True,
8075
+ root_grouped_patches=False
8076
+ ):
8077
+
8078
+ if max_num_patches_per_chord > 4:
8079
+ n_patches = 4
8080
+ elif max_num_patches_per_chord < 1:
8081
+ n_patches = 1
8082
+ else:
8083
+ n_patches = max_num_patches_per_chord
8084
+
8085
+ cscore = chordify_score([1000, sorted(escore_notes, key=lambda x: (x[1], x[6]))])
8086
+
8087
+ new_escore_notes = []
8088
+
8089
+ for c in cscore:
8090
+
8091
+ if group_patches:
8092
+ patches_set = sorted(set([e[6] for e in c]))
8093
+ trg_patch_list = []
8094
+ seen = []
8095
+ for p in patches_set:
8096
+ if p // 8 not in seen:
8097
+ trg_patch_list.append(p)
8098
+ seen.append(p // 8)
8099
+
8100
+ trg_patch_list = sorted(trg_patch_list)
8101
+
8102
+ else:
8103
+ trg_patch_list = sorted(set([e[6] for e in c]))
8104
+
8105
+ if 128 in trg_patch_list and n_patches > 1:
8106
+ trg_patch_list = trg_patch_list[:n_patches-1] + [128]
8107
+ else:
8108
+ trg_patch_list = trg_patch_list[:n_patches]
8109
+
8110
+ for ccc in c:
8111
+
8112
+ cc = copy.deepcopy(ccc)
8113
+
8114
+ if group_patches:
8115
+ if cc[6] // 8 in [t // 8 for t in trg_patch_list]:
8116
+ if root_grouped_patches:
8117
+ cc[6] = (cc[6] // 8) * 8
8118
+ new_escore_notes.append(cc)
8119
+
8120
+ else:
8121
+ if cc[6] in trg_patch_list:
8122
+ new_escore_notes.append(cc)
8123
+
8124
+ return new_escore_notes
8125
+
8126
+ ###################################################################################
8127
+
8128
+ def escore_notes_to_image_matrix(escore_notes,
8129
+ num_img_channels=3,
8130
+ filter_out_zero_rows=False,
8131
+ filter_out_duplicate_rows=False,
8132
+ flip_matrix=False,
8133
+ reverse_matrix=False
8134
+ ):
8135
+
8136
+ escore_notes = sorted(escore_notes, key=lambda x: (x[1], x[6]))
8137
+
8138
+ if num_img_channels > 1:
8139
+ n_mat_channels = 3
8140
+ else:
8141
+ n_mat_channels = 1
8142
+
8143
+ if escore_notes:
8144
+ last_time = escore_notes[-1][1]
8145
+ last_notes = [e for e in escore_notes if e[1] == last_time]
8146
+ max_last_dur = max([e[2] for e in last_notes])
8147
+
8148
+ time_range = last_time+max_last_dur
8149
+
8150
+ escore_matrix = []
8151
+
8152
+ escore_matrix = [[0] * 128 for _ in range(time_range)]
8153
+
8154
+ for note in escore_notes:
8155
+
8156
+ etype, time, duration, chan, pitch, velocity, pat = note
8157
+
8158
+ time = max(0, time)
8159
+ duration = max(2, duration)
8160
+ chan = max(0, min(15, chan))
8161
+ pitch = max(0, min(127, pitch))
8162
+ velocity = max(0, min(127, velocity))
8163
+ patch = max(0, min(128, pat))
8164
+
8165
+ if chan != 9:
8166
+ pat = patch + 128
8167
+ else:
8168
+ pat = 127
8169
+
8170
+ seen_pats = []
8171
+
8172
+ for t in range(time, min(time + duration, time_range)):
8173
+
8174
+ mat_value = escore_matrix[t][pitch]
8175
+
8176
+ mat_value_0 = (mat_value // (256 * 256)) % 256
8177
+ mat_value_1 = (mat_value // 256) % 256
8178
+
8179
+ cur_num_chans = 0
8180
+
8181
+ if 0 < mat_value < 256 and pat not in seen_pats:
8182
+ cur_num_chans = 1
8183
+ elif 256 < mat_value < (256 * 256) and pat not in seen_pats:
8184
+ cur_num_chans = 2
8185
+
8186
+ if cur_num_chans < n_mat_channels:
8187
+
8188
+ if n_mat_channels == 1:
8189
+
8190
+ escore_matrix[t][pitch] = pat
8191
+ seen_pats.append(pat)
8192
+
8193
+ elif n_mat_channels == 3:
8194
+
8195
+ if cur_num_chans == 0:
8196
+ escore_matrix[t][pitch] = pat
8197
+ seen_pats.append(pat)
8198
+ elif cur_num_chans == 1:
8199
+ escore_matrix[t][pitch] = (256 * 256 * mat_value_0) + (256 * pat)
8200
+ seen_pats.append(pat)
8201
+ elif cur_num_chans == 2:
8202
+ escore_matrix[t][pitch] = (256 * 256 * mat_value_0) + (256 * mat_value_1) + pat
8203
+ seen_pats.append(pat)
8204
+
8205
+ if filter_out_zero_rows:
8206
+ escore_matrix = [e for e in escore_matrix if sum(e) != 0]
8207
+
8208
+ if filter_out_duplicate_rows:
8209
+
8210
+ dd_escore_matrix = []
8211
+
8212
+ pr = [-1] * 128
8213
+ for e in escore_matrix:
8214
+ if e != pr:
8215
+ dd_escore_matrix.append(e)
8216
+ pr = e
8217
+
8218
+ escore_matrix = dd_escore_matrix
8219
+
8220
+ if flip_matrix:
8221
+
8222
+ temp_matrix = []
8223
+
8224
+ for m in escore_matrix:
8225
+ temp_matrix.append(m[::-1])
8226
+
8227
+ escore_matrix = temp_matrix
8228
+
8229
+ if reverse_matrix:
8230
+ escore_matrix = escore_matrix[::-1]
8231
+
8232
+ return escore_matrix
8233
+
8234
+ else:
8235
+ return None
8236
+
8237
+ ###################################################################################
8238
+
8239
+ def find_value_power(value, number):
8240
+ return math.floor(math.log(value, number))
8241
+
8242
+ ###################################################################################
8243
+
8244
+ def image_matrix_to_original_escore_notes(image_matrix,
8245
+ velocity=-1
8246
+ ):
8247
+
8248
+ result = []
8249
+
8250
+ for j in range(len(image_matrix[0])):
8251
+
8252
+ count = 1
8253
+
8254
+ for i in range(1, len(image_matrix)):
8255
+
8256
+ if image_matrix[i][j] != 0 and image_matrix[i][j] == image_matrix[i-1][j]:
8257
+ count += 1
8258
+
8259
+ else:
8260
+ if count > 1:
8261
+ result.append([i-count, count, j, image_matrix[i-1][j]])
8262
+
8263
+ else:
8264
+ if image_matrix[i-1][j] != 0:
8265
+ result.append([i-count, count, j, image_matrix[i-1][j]])
8266
+
8267
+ count = 1
8268
+
8269
+ if count > 1:
8270
+ result.append([len(image_matrix)-count, count, j, image_matrix[-1][j]])
8271
+
8272
+ else:
8273
+ if image_matrix[i-1][j] != 0:
8274
+ result.append([i-count, count, j, image_matrix[i-1][j]])
8275
+
8276
+ result.sort(key=lambda x: (x[0], -x[2]))
8277
+
8278
+ original_escore_notes = []
8279
+
8280
+ vel = velocity
8281
+
8282
+ for r in result:
8283
+
8284
+ if velocity == -1:
8285
+ vel = max(40, r[2])
8286
+
8287
+ ptc0 = 0
8288
+ ptc1 = 0
8289
+ ptc2 = 0
8290
+
8291
+ if find_value_power(r[3], 256) == 0:
8292
+ ptc0 = r[3] % 256
8293
+
8294
+ elif find_value_power(r[3], 256) == 1:
8295
+ ptc0 = r[3] // 256
8296
+ ptc1 = (r[3] // 256) % 256
8297
+
8298
+ elif find_value_power(r[3], 256) == 2:
8299
+ ptc0 = (r[3] // 256) // 256
8300
+ ptc1 = (r[3] // 256) % 256
8301
+ ptc2 = r[3] % 256
8302
+
8303
+ ptcs = [ptc0, ptc1, ptc2]
8304
+ patches = [p for p in ptcs if p != 0]
8305
+
8306
+ for i, p in enumerate(patches):
8307
+
8308
+ if p < 128:
8309
+ patch = 128
8310
+ channel = 9
8311
+
8312
+ else:
8313
+ patch = p % 128
8314
+ chan = p // 8
8315
+
8316
+ if chan == 9:
8317
+ chan += 1
8318
+
8319
+ channel = min(15, chan)
8320
+
8321
+ original_escore_notes.append(['note', r[0], r[1], channel, r[2], vel, patch])
8322
+
8323
+ output_score = sorted(original_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
8324
+
8325
+ adjust_score_velocities(output_score, 127)
8326
+
8327
+ return output_score
8328
+
8329
+ ###################################################################################
8330
+
8331
+ def escore_notes_delta_times(escore_notes,
8332
+ timings_index=1,
8333
+ channels_index=3,
8334
+ omit_zeros=False,
8335
+ omit_drums=False
8336
+ ):
8337
+
8338
+ if omit_drums:
8339
+
8340
+ score = [e for e in escore_notes if e[channels_index] != 9]
8341
+ dtimes = [score[0][timings_index]] + [b[timings_index]-a[timings_index] for a, b in zip(score[:-1], score[1:])]
8342
+
8343
+ else:
8344
+ dtimes = [escore_notes[0][timings_index]] + [b[timings_index]-a[timings_index] for a, b in zip(escore_notes[:-1], escore_notes[1:])]
8345
+
8346
+ if omit_zeros:
8347
+ dtimes = [d for d in dtimes if d != 0]
8348
+
8349
+ return dtimes
8350
+
8351
+ ###################################################################################
8352
+
8353
+ def monophonic_check(escore_notes, times_index=1):
8354
+ return len(escore_notes) == len(set([e[times_index] for e in escore_notes]))
8355
+
8356
+ ###################################################################################
8357
+
8358
+ def count_escore_notes_patches(escore_notes, patches_index=6):
8359
+ return [list(c) for c in Counter([e[patches_index] for e in escore_notes]).most_common()]
8360
+
8361
+ ###################################################################################
8362
+
8363
+ def escore_notes_medley(list_of_escore_notes,
8364
+ list_of_labels=None,
8365
+ pause_time_value=255
8366
+ ):
8367
+
8368
+ if list_of_labels is not None:
8369
+ labels = [str(l) for l in list_of_labels] + ['No label'] * (len(list_of_escore_notes)-len(list_of_labels))
8370
+
8371
+ medley = []
8372
+
8373
+ time = 0
8374
+
8375
+ for i, m in enumerate(list_of_escore_notes):
8376
+
8377
+ if list_of_labels is not None:
8378
+ medley.append(['text_event', time, labels[i]])
8379
+
8380
+ pe = m[0]
8381
+
8382
+ for mm in m:
8383
+
8384
+ time += mm[1] - pe[1]
8385
+
8386
+ mmm = copy.deepcopy(mm)
8387
+ mmm[1] = time
8388
+
8389
+ medley.append(mmm)
8390
+
8391
+ pe = mm
8392
+
8393
+ time += pause_time_value
8394
+
8395
+ return medley
8396
+
8397
+ ###################################################################################
8398
+
8399
+ def proportions_counter(list_of_values):
8400
+
8401
+ counts = Counter(list_of_values).most_common()
8402
+ clen = sum([c[1] for c in counts])
8403
+
8404
+ return [[c[0], c[1], c[1] / clen] for c in counts]
8405
+
8406
+ ###################################################################################
8407
+
8408
+ def smooth_escore_notes(escore_notes):
8409
+
8410
+ values = [e[4] % 24 for e in escore_notes]
8411
+
8412
+ smoothed = [values[0]]
8413
+
8414
+ for i in range(1, len(values)):
8415
+ if abs(smoothed[-1] - values[i]) >= 12:
8416
+ if smoothed[-1] < values[i]:
8417
+ smoothed.append(values[i] - 12)
8418
+ else:
8419
+ smoothed.append(values[i] + 12)
8420
+ else:
8421
+ smoothed.append(values[i])
8422
+
8423
+ smoothed_score = copy.deepcopy(escore_notes)
8424
+
8425
+ for i, e in enumerate(smoothed_score):
8426
+ esn_octave = escore_notes[i][4] // 12
8427
+ e[4] = (esn_octave * 12) + smoothed[i]
8428
+
8429
+ return smoothed_score
8430
+
8431
+ ###################################################################################
8432
+
8433
+ def add_base_to_escore_notes(escore_notes,
8434
+ base_octave=2,
8435
+ base_channel=2,
8436
+ base_patch=35,
8437
+ base_max_velocity=120,
8438
+ return_base=False
8439
+ ):
8440
+
8441
+
8442
+ score = copy.deepcopy(escore_notes)
8443
+
8444
+ cscore = chordify_score([1000, score])
8445
+
8446
+ base_score = []
8447
+
8448
+ for c in cscore:
8449
+ chord = sorted([e for e in c if e[3] != 9], key=lambda x: x[4], reverse=True)
8450
+ base_score.append(chord[-1])
8451
+
8452
+ base_score = smooth_escore_notes(base_score)
8453
+
8454
+ for e in base_score:
8455
+ e[3] = base_channel
8456
+ e[4] = (base_octave * 12) + (e[4] % 12)
8457
+ e[5] = e[4]
8458
+ e[6] = base_patch
8459
+
8460
+ adjust_score_velocities(base_score, base_max_velocity)
8461
+
8462
+ if return_base:
8463
+ final_score = sorted(base_score, key=lambda x: (x[1], -x[4], x[6]))
8464
+
8465
+ else:
8466
+ final_score = sorted(escore_notes + base_score, key=lambda x: (x[1], -x[4], x[6]))
8467
+
8468
+ return final_score
8469
+
8470
+ ###################################################################################
8471
+
8472
+ def add_drums_to_escore_notes(escore_notes,
8473
+ heavy_drums_pitches=[36, 38, 47],
8474
+ heavy_drums_velocity=110,
8475
+ light_drums_pitches=[51, 54],
8476
+ light_drums_velocity=127,
8477
+ drums_max_velocity=127,
8478
+ drums_ratio_time_divider=4,
8479
+ return_drums=False
8480
+ ):
8481
+
8482
+ score = copy.deepcopy([e for e in escore_notes if e[3] != 9])
8483
+
8484
+ cscore = chordify_score([1000, score])
8485
+
8486
+ drums_score = []
8487
+
8488
+ for c in cscore:
8489
+ min_dur = max(1, min([e[2] for e in c]))
8490
+ if not (c[0][1] % drums_ratio_time_divider):
8491
+ drum_note = ['note', c[0][1], min_dur, 9, heavy_drums_pitches[c[0][4] % len(heavy_drums_pitches)], heavy_drums_velocity, 128]
8492
+ else:
8493
+ drum_note = ['note', c[0][1], min_dur, 9, light_drums_pitches[c[0][4] % len(light_drums_pitches)], light_drums_velocity, 128]
8494
+ drums_score.append(drum_note)
8495
+
8496
+ adjust_score_velocities(drums_score, drums_max_velocity)
8497
+
8498
+ if return_drums:
8499
+ final_score = sorted(drums_score, key=lambda x: (x[1], -x[4], x[6]))
8500
+
8501
+ else:
8502
+ final_score = sorted(score + drums_score, key=lambda x: (x[1], -x[4], x[6]))
8503
+
8504
+ return final_score
8505
+
8506
+ ###################################################################################
8507
+
8508
+ def find_pattern_start_indexes(values, pattern):
8509
+
8510
+ start_indexes = []
8511
+
8512
+ count = 0
8513
+
8514
+ for i in range(len(values)- len(pattern)):
8515
+ chunk = values[i:i+len(pattern)]
8516
+
8517
+ if chunk == pattern:
8518
+ start_indexes.append(i)
8519
+
8520
+ return start_indexes
8521
+
8522
+ ###################################################################################
8523
+
8524
+ def escore_notes_lrno_pattern(escore_notes, mode='chords'):
8525
+
8526
+ cscore = chordify_score([1000, escore_notes])
8527
+
8528
+ checked_cscore = advanced_check_and_fix_chords_in_chordified_score(cscore)
8529
+
8530
+ chords_toks = []
8531
+ chords_idxs = []
8532
+
8533
+ for i, c in enumerate(checked_cscore[0]):
8534
+
8535
+ pitches = sorted([p[4] for p in c if p[3] != 9], reverse=True)
8536
+ tchord = pitches_to_tones_chord(pitches)
8537
+
8538
+ if tchord:
8539
+
8540
+ if mode == 'chords':
8541
+ token = ALL_CHORDS_FULL.index(tchord)
8542
+
8543
+ elif mode == 'high pitches':
8544
+ token = pitches[0]
8545
+
8546
+ elif mode == 'high pitches tones':
8547
+ token = pitches[0] % 12
8548
+
8549
+ else:
8550
+ token = ALL_CHORDS_FULL.index(tchord)
8551
+
8552
+ chords_toks.append(token)
8553
+ chords_idxs.append(i)
8554
+
8555
+ lrno_pats = find_lrno_patterns(chords_toks)
8556
+
8557
+ if lrno_pats:
8558
+
8559
+ lrno_pattern = list(lrno_pats[0][2])
8560
+
8561
+ start_idx = chords_idxs[find_pattern_start_indexes(chords_toks, lrno_pattern)[0]]
8562
+ end_idx = chords_idxs[start_idx + len(lrno_pattern)]
8563
+
8564
+ return recalculate_score_timings(flatten(cscore[start_idx:end_idx]))
8565
+
8566
+ else:
8567
+ return None
8568
+
8569
+ ###################################################################################
8570
+
8571
+ def chordified_score_pitches(chordified_score,
8572
+ mode='dominant',
8573
+ return_tones=False,
8574
+ omit_drums=True,
8575
+ score_patch=-1,
8576
+ channels_index=3,
8577
+ pitches_index=4,
8578
+ patches_index=6
8579
+ ):
8580
+
8581
+ results = []
8582
+
8583
+ for c in chordified_score:
8584
+
8585
+ if -1 < score_patch < 128:
8586
+ ptcs = sorted([e[pitches_index] for e in c if e[channels_index] != 9 and e[patches_index] == score_patch], reverse=True)
8587
+
8588
+ else:
8589
+ ptcs = sorted([e[pitches_index] for e in c if e[channels_index] != 9], reverse=True)
8590
+
8591
+ if ptcs:
8592
+
8593
+ if mode == 'dominant':
8594
+
8595
+ mtone = statistics.mode([p % 12 for p in ptcs])
8596
+
8597
+ if return_tones:
8598
+ results.append(mtone)
8599
+
8600
+ else:
8601
+ results.append(sorted(set([p for p in ptcs if p % 12 == mtone]), reverse=True))
8602
+
8603
+ elif mode == 'high':
8604
+
8605
+ if return_tones:
8606
+ results.append(ptcs[0] % 12)
8607
+
8608
+ else:
8609
+ results.append([ptcs[0]])
8610
+
8611
+ elif mode == 'base':
8612
+
8613
+ if return_tones:
8614
+ results.append(ptcs[-1] % 12)
8615
+
8616
+ else:
8617
+ results.append([ptcs[-1]])
8618
+
8619
+ elif mode == 'average':
8620
+
8621
+ if return_tones:
8622
+ results.append(statistics.mean(ptcs) % 12)
8623
+
8624
+ else:
8625
+ results.append([statistics.mean(ptcs)])
8626
+
8627
+ else:
8628
+
8629
+ mtone = statistics.mode([p % 12 for p in ptcs])
8630
+
8631
+ if return_tones:
8632
+ results.append(mtone)
8633
+
8634
+ else:
8635
+ results.append(sorted(set([p for p in ptcs if p % 12 == mtone]), reverse=True))
8636
+
8637
+ else:
8638
+
8639
+ if not omit_drums:
8640
+
8641
+ if return_tones:
8642
+ results.append(-1)
8643
+
8644
+ else:
8645
+ results.append([-1])
8646
+
8647
+ return results
8648
+
8649
+ ###################################################################################
8650
+
8651
+ def escore_notes_times_tones(escore_notes,
8652
+ tones_mode='dominant',
8653
+ return_abs_times=True,
8654
+ omit_drums=False
8655
+ ):
8656
+
8657
+ cscore = chordify_score([1000, escore_notes])
8658
+
8659
+ tones = chordified_score_pitches(cscore, return_tones=True, mode=tones_mode, omit_drums=omit_drums)
8660
+
8661
+ if return_abs_times:
8662
+ times = sorted([c[0][1] for c in cscore])
8663
+
8664
+ else:
8665
+ times = escore_notes_delta_times(escore_notes, omit_zeros=True, omit_drums=omit_drums)
8666
+
8667
+ if len(times) != len(tones):
8668
+ times = [0] + times
8669
+
8670
+ return [[t, to] for t, to in zip(times, tones)]
8671
+
8672
+ ###################################################################################
8673
+
8674
+ def escore_notes_middle(escore_notes,
8675
+ length=10,
8676
+ use_chords=True
8677
+ ):
8678
+
8679
+ if use_chords:
8680
+ score = chordify_score([1000, escore_notes])
8681
+
8682
+ else:
8683
+ score = escore_notes
8684
+
8685
+ middle_idx = len(score) // 2
8686
+
8687
+ slen = min(len(score) // 2, length // 2)
8688
+
8689
+ start_idx = middle_idx - slen
8690
+ end_idx = middle_idx + slen
8691
+
8692
+ if use_chords:
8693
+ return flatten(score[start_idx:end_idx])
8694
+
8695
+ else:
8696
+ return score[start_idx:end_idx]
8697
+
8698
+ ###################################################################################
8699
+
8700
+ ALL_CHORDS_FULL = [[0], [0, 3], [0, 3, 5], [0, 3, 5, 8], [0, 3, 5, 9], [0, 3, 5, 10], [0, 3, 6],
8701
+ [0, 3, 6, 9], [0, 3, 6, 10], [0, 3, 7], [0, 3, 7, 10], [0, 3, 8], [0, 3, 9],
8702
+ [0, 3, 10], [0, 4], [0, 4, 6], [0, 4, 6, 9], [0, 4, 6, 10], [0, 4, 7],
8703
+ [0, 4, 7, 10], [0, 4, 8], [0, 4, 9], [0, 4, 10], [0, 5], [0, 5, 8], [0, 5, 9],
8704
+ [0, 5, 10], [0, 6], [0, 6, 9], [0, 6, 10], [0, 7], [0, 7, 10], [0, 8], [0, 9],
8705
+ [0, 10], [1], [1, 4], [1, 4, 6], [1, 4, 6, 9], [1, 4, 6, 10], [1, 4, 6, 11],
8706
+ [1, 4, 7], [1, 4, 7, 10], [1, 4, 7, 11], [1, 4, 8], [1, 4, 8, 11], [1, 4, 9],
8707
+ [1, 4, 10], [1, 4, 11], [1, 5], [1, 5, 8], [1, 5, 8, 11], [1, 5, 9],
8708
+ [1, 5, 10], [1, 5, 11], [1, 6], [1, 6, 9], [1, 6, 10], [1, 6, 11], [1, 7],
8709
+ [1, 7, 10], [1, 7, 11], [1, 8], [1, 8, 11], [1, 9], [1, 10], [1, 11], [2],
8710
+ [2, 5], [2, 5, 8], [2, 5, 8, 11], [2, 5, 9], [2, 5, 10], [2, 5, 11], [2, 6],
8711
+ [2, 6, 9], [2, 6, 10], [2, 6, 11], [2, 7], [2, 7, 10], [2, 7, 11], [2, 8],
8712
+ [2, 8, 11], [2, 9], [2, 10], [2, 11], [3], [3, 5], [3, 5, 8], [3, 5, 8, 11],
8713
+ [3, 5, 9], [3, 5, 10], [3, 5, 11], [3, 6], [3, 6, 9], [3, 6, 10], [3, 6, 11],
8714
+ [3, 7], [3, 7, 10], [3, 7, 11], [3, 8], [3, 8, 11], [3, 9], [3, 10], [3, 11],
8715
+ [4], [4, 6], [4, 6, 9], [4, 6, 10], [4, 6, 11], [4, 7], [4, 7, 10], [4, 7, 11],
8716
+ [4, 8], [4, 8, 11], [4, 9], [4, 10], [4, 11], [5], [5, 8], [5, 8, 11], [5, 9],
8717
+ [5, 10], [5, 11], [6], [6, 9], [6, 10], [6, 11], [7], [7, 10], [7, 11], [8],
8718
+ [8, 11], [9], [10], [11]]
8719
+
8720
+ ###################################################################################
8721
+ #
8722
+ # This is the end of the TMIDI X Python module
8723
+ #
8724
  ###################################################################################