asigalov61 commited on
Commit
6f0f783
·
verified ·
1 Parent(s): 5850ceb

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +936 -10
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]
@@ -5350,7 +5378,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 +5391,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
 
@@ -6861,7 +6892,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 = []
@@ -6888,8 +6919,14 @@ def binary_matrix_to_original_escore_notes(binary_matrix,
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
 
@@ -7034,6 +7071,895 @@ def transpose_escore_notes_to_pitch(escore_notes,
7034
 
7035
  ###################################################################################
7036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7037
  # This is the end of the TMIDI X Python module
7038
 
7039
  ###################################################################################
 
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]
 
5378
 
5379
  ###################################################################################
5380
 
5381
+ def recalculate_score_timings(score,
5382
+ start_time=0,
5383
+ timings_index=1
5384
+ ):
5385
 
5386
  rscore = copy.deepcopy(score)
5387
 
 
5391
 
5392
  for e in rscore:
5393
 
5394
+ dtime = e[timings_index] - pe[timings_index]
5395
  pe = copy.deepcopy(e)
5396
  abs_time += dtime
5397
+ e[timings_index] = abs_time
5398
 
5399
  return rscore
5400
 
 
6892
  def binary_matrix_to_original_escore_notes(binary_matrix,
6893
  channel=0,
6894
  patch=0,
6895
+ velocity=-1
6896
  ):
6897
 
6898
  result = []
 
6919
 
6920
  original_escore_notes = []
6921
 
6922
+ vel = velocity
6923
+
6924
  for r in result:
6925
+
6926
+ if velocity == -1:
6927
+ vel = max(40, r[2])
6928
+
6929
+ original_escore_notes.append(['note', r[0], r[1], channel, r[2], vel, patch])
6930
 
6931
  return sorted(original_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
6932
 
 
7071
 
7072
  ###################################################################################
7073
 
7074
+ CHORDS_TYPES = ['WHITE', 'BLACK', 'UNKNOWN', 'MIXED WHITE', 'MIXED BLACK', 'MIXED GRAY']
7075
+
7076
+ ###################################################################################
7077
+
7078
+ def tones_chord_type(tones_chord,
7079
+ return_chord_type_index=True,
7080
+ use_filtered_chords=True
7081
+ ):
7082
+
7083
+ WN = WHITE_NOTES
7084
+ BN = BLACK_NOTES
7085
+ MX = WHITE_NOTES + BLACK_NOTES
7086
+
7087
+ if use_filtered_chords:
7088
+ CHORDS = ALL_CHORDS_FILTERED
7089
+
7090
+ else:
7091
+ CHORDS = ALL_CHORDS_SORTED
7092
+
7093
+ tones_chord = sorted(tones_chord)
7094
+
7095
+ ctype = 'UNKNOWN'
7096
+
7097
+ if tones_chord in CHORDS:
7098
+
7099
+ if sorted(set(tones_chord) & set(WN)) == tones_chord:
7100
+ ctype = 'WHITE'
7101
+
7102
+ elif sorted(set(tones_chord) & set(BN)) == tones_chord:
7103
+ ctype = 'BLACK'
7104
+
7105
+ if len(tones_chord) > 1 and sorted(set(tones_chord) & set(MX)) == tones_chord:
7106
+
7107
+ if len(sorted(set(tones_chord) & set(WN))) == len(sorted(set(tones_chord) & set(BN))):
7108
+ ctype = 'MIXED GRAY'
7109
+
7110
+ elif len(sorted(set(tones_chord) & set(WN))) > len(sorted(set(tones_chord) & set(BN))):
7111
+ ctype = 'MIXED WHITE'
7112
+
7113
+ elif len(sorted(set(tones_chord) & set(WN))) < len(sorted(set(tones_chord) & set(BN))):
7114
+ ctype = 'MIXED BLACK'
7115
+
7116
+ if return_chord_type_index:
7117
+ return CHORDS_TYPES.index(ctype)
7118
+
7119
+ else:
7120
+ return ctype
7121
+
7122
+ ###################################################################################
7123
+
7124
+ def tone_type(tone,
7125
+ return_tone_type_index=True
7126
+ ):
7127
+
7128
+ tone = tone % 12
7129
+
7130
+ if tone in BLACK_NOTES:
7131
+ if return_tone_type_index:
7132
+ return CHORDS_TYPES.index('BLACK')
7133
+ else:
7134
+ return "BLACK"
7135
+
7136
+ else:
7137
+ if return_tone_type_index:
7138
+ return CHORDS_TYPES.index('WHITE')
7139
+ else:
7140
+ return "WHITE"
7141
+
7142
+ ###################################################################################
7143
+
7144
+ def lists_sym_differences(src_list, trg_list):
7145
+ return list(set(src_list) ^ set(trg_list))
7146
+
7147
+ ###################################################################################
7148
+
7149
+ def lists_differences(long_list, short_list):
7150
+ return list(set(long_list) - set(short_list))
7151
+
7152
+ ###################################################################################
7153
+
7154
+ def find_best_tones_chord(src_tones_chords,
7155
+ trg_tones_chords,
7156
+ find_longest=True
7157
+ ):
7158
+
7159
+ not_seen_trg_chords = []
7160
+
7161
+ max_len = 0
7162
+
7163
+ for tc in trg_tones_chords:
7164
+ if sorted(tc) in src_tones_chords:
7165
+ not_seen_trg_chords.append(sorted(tc))
7166
+ max_len = max(max_len, len(tc))
7167
+
7168
+ if not not_seen_trg_chords:
7169
+ max_len = len(max(trg_tones_chords, key=len))
7170
+ not_seen_trg_chords = trg_tones_chords
7171
+
7172
+ if find_longest:
7173
+ return random.choice([c for c in not_seen_trg_chords if len(c) == max_len])
7174
+
7175
+ else:
7176
+ return random.choice(not_seen_trg_chords)
7177
+
7178
+ ###################################################################################
7179
+
7180
+ def find_matching_tones_chords(tones_chord,
7181
+ matching_chord_length=-1,
7182
+ match_chord_type=True,
7183
+ use_filtered_chords=True
7184
+ ):
7185
+
7186
+ if use_filtered_chords:
7187
+ CHORDS = ALL_CHORDS_FILTERED
7188
+ else:
7189
+ CHORDS = ALL_CHORDS_SORTED
7190
+
7191
+ tones_chord = sorted(tones_chord)
7192
+
7193
+ tclen = len(tones_chord)
7194
+
7195
+ tctype = tones_chord_type(tones_chord, use_filtered_chords=use_filtered_chords)
7196
+
7197
+ matches = []
7198
+
7199
+ for tc in CHORDS:
7200
+
7201
+ if matching_chord_length == -1:
7202
+ if len(tc) > tclen:
7203
+ if sorted(lists_intersections(tc, tones_chord)) == tones_chord:
7204
+ if match_chord_type:
7205
+ if tones_chord_type(tc, use_filtered_chords=use_filtered_chords) == tctype:
7206
+ tcdiffs = lists_differences(tc, tones_chord)
7207
+ if all(tone_type(d) == tctype % 3 for d in tcdiffs):
7208
+ matches.append(tc)
7209
+ else:
7210
+ matches.append(tc)
7211
+
7212
+ else:
7213
+
7214
+ if len(tc) == max(tclen, matching_chord_length):
7215
+ if sorted(lists_intersections(tc, tones_chord)) == tones_chord:
7216
+ if match_chord_type:
7217
+ if tones_chord_type(tc, use_filtered_chords=use_filtered_chords) == tctype:
7218
+ tcdiffs = lists_differences(tc, tones_chord)
7219
+ if all(tone_type(d) == tctype % 3 for d in tcdiffs):
7220
+ matches.append(tc)
7221
+ else:
7222
+ matches.append(tc)
7223
+
7224
+ return sorted(matches, key=len)
7225
+
7226
+ ###################################################################################
7227
+
7228
+ def adjust_list_of_values_to_target_average(list_of_values,
7229
+ trg_avg,
7230
+ min_value,
7231
+ max_value
7232
+ ):
7233
+
7234
+ filtered_values = [value for value in list_of_values if min_value <= value <= max_value]
7235
+
7236
+ if not filtered_values:
7237
+ return list_of_values
7238
+
7239
+ current_avg = sum(filtered_values) / len(filtered_values)
7240
+ scale_factor = trg_avg / current_avg
7241
+
7242
+ adjusted_values = [value * scale_factor for value in filtered_values]
7243
+
7244
+ total_difference = trg_avg * len(filtered_values) - sum(adjusted_values)
7245
+ adjustment_per_value = total_difference / len(filtered_values)
7246
+
7247
+ final_values = [value + adjustment_per_value for value in adjusted_values]
7248
+
7249
+ while abs(sum(final_values) / len(final_values) - trg_avg) > 1e-6:
7250
+ total_difference = trg_avg * len(final_values) - sum(final_values)
7251
+ adjustment_per_value = total_difference / len(final_values)
7252
+ final_values = [value + adjustment_per_value for value in final_values]
7253
+
7254
+ final_values = [round(value) for value in final_values]
7255
+
7256
+ adjusted_values = copy.deepcopy(list_of_values)
7257
+
7258
+ j = 0
7259
+
7260
+ for i in range(len(adjusted_values)):
7261
+ if min_value <= adjusted_values[i] <= max_value:
7262
+ adjusted_values[i] = final_values[j]
7263
+ j += 1
7264
+
7265
+ return adjusted_values
7266
+
7267
+ ###################################################################################
7268
+
7269
+ def adjust_escore_notes_to_average(escore_notes,
7270
+ trg_avg,
7271
+ min_value=1,
7272
+ max_value=4000,
7273
+ times_index=1,
7274
+ durs_index=2,
7275
+ score_is_delta=False,
7276
+ return_delta_scpre=False
7277
+ ):
7278
+ if score_is_delta:
7279
+ delta_escore_notes = copy.deepcopy(escore_notes)
7280
+
7281
+ else:
7282
+ delta_escore_notes = delta_score_notes(escore_notes)
7283
+
7284
+ times = [[e[times_index], e[durs_index]] for e in delta_escore_notes]
7285
+
7286
+ filtered_values = [value for value in times if min_value <= value[0] <= max_value]
7287
+
7288
+ if not filtered_values:
7289
+ return escore_notes
7290
+
7291
+ current_avg = sum([v[0] for v in filtered_values]) / len([v[0] for v in filtered_values])
7292
+ scale_factor = trg_avg / current_avg
7293
+
7294
+ adjusted_values = [[value[0] * scale_factor, value[1] * scale_factor] for value in filtered_values]
7295
+
7296
+ total_difference = trg_avg * len([v[0] for v in filtered_values]) - sum([v[0] for v in adjusted_values])
7297
+ adjustment_per_value = total_difference / len(filtered_values)
7298
+
7299
+ final_values = [[value[0] + adjustment_per_value, value[1] + adjustment_per_value] for value in adjusted_values]
7300
+
7301
+ while abs(sum([v[0] for v in final_values]) / len(final_values) - trg_avg) > 1e-6:
7302
+ total_difference = trg_avg * len(final_values) - sum([v[0] for v in final_values])
7303
+ adjustment_per_value = total_difference / len(final_values)
7304
+ final_values = [[value[0] + adjustment_per_value, value[1] + adjustment_per_value] for value in final_values]
7305
+
7306
+ final_values = [[round(value[0]), round(value[1])] for value in final_values]
7307
+
7308
+ adjusted_delta_score = copy.deepcopy(delta_escore_notes)
7309
+
7310
+ j = 0
7311
+
7312
+ for i in range(len(adjusted_delta_score)):
7313
+ if min_value <= adjusted_delta_score[i][1] <= max_value:
7314
+ adjusted_delta_score[i][times_index] = final_values[j][0]
7315
+ adjusted_delta_score[i][durs_index] = final_values[j][1]
7316
+ j += 1
7317
+
7318
+ adjusted_escore_notes = delta_score_to_abs_score(adjusted_delta_score)
7319
+
7320
+ if return_delta_scpre:
7321
+ return adjusted_delta_score
7322
+
7323
+ else:
7324
+ return adjusted_escore_notes
7325
+
7326
+ ###################################################################################
7327
+
7328
+ def harmonize_enhanced_melody_score_notes_to_ms_SONG(escore_notes,
7329
+ melody_velocity=-1,
7330
+ melody_channel=3,
7331
+ melody_patch=40,
7332
+ melody_base_octave=4,
7333
+ harmonized_tones_chords_velocity=-1,
7334
+ harmonized_tones_chords_channel=0,
7335
+ harmonized_tones_chords_patch=0
7336
+ ):
7337
+
7338
+ harmonized_tones_chords = harmonize_enhanced_melody_score_notes(escore_notes)
7339
+
7340
+ harm_escore_notes = []
7341
+
7342
+ time = 0
7343
+
7344
+ for i, note in enumerate(escore_notes):
7345
+
7346
+ time = note[1]
7347
+ dur = note[2]
7348
+ ptc = note[4]
7349
+
7350
+ if melody_velocity == -1:
7351
+ vel = int(110 + ((ptc % 12) * 1.5))
7352
+ else:
7353
+ vel = melody_velocity
7354
+
7355
+ harm_escore_notes.append(['note', time, dur, melody_channel, ptc, vel, melody_patch])
7356
+
7357
+ for t in harmonized_tones_chords[i]:
7358
+
7359
+ ptc = (melody_base_octave * 12) + t
7360
+
7361
+ if harmonized_tones_chords_velocity == -1:
7362
+ vel = int(80 + ((ptc % 12) * 1.5))
7363
+ else:
7364
+ vel = harmonized_tones_chords_velocity
7365
+
7366
+ harm_escore_notes.append(['note', time, dur, harmonized_tones_chords_channel, ptc, vel, harmonized_tones_chords_patch])
7367
+
7368
+ return sorted(harm_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
7369
+
7370
+ ###################################################################################
7371
+
7372
+ def check_and_fix_pitches_chord(pitches_chord,
7373
+ use_filtered_chords=True
7374
+ ):
7375
+
7376
+ pitches_chord = sorted(pitches_chord, reverse=True)
7377
+
7378
+ if use_filtered_chords:
7379
+ CHORDS = ALL_CHORDS_FILTERED
7380
+ else:
7381
+ CHORDS = ALL_CHORDS_SORTED
7382
+
7383
+ tones_chord = sorted(set([p % 12 for p in pitches_chord]))
7384
+
7385
+ if tones_chord not in CHORDS:
7386
+
7387
+ if len(tones_chord) == 2:
7388
+
7389
+ tones_counts = Counter([p % 12 for p in pitches_chord]).most_common()
7390
+
7391
+ if tones_counts[0][1] > 1:
7392
+ tones_chord = [tones_counts[0][0]]
7393
+ elif tones_counts[1][1] > 1:
7394
+ tones_chord = [tones_counts[1][0]]
7395
+ else:
7396
+ tones_chord = [pitches_chord[0] % 12]
7397
+
7398
+ if len(tones_chord) > 2:
7399
+
7400
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord)-2, 0, -1) for comb in combinations(tones_chord, i+1)]
7401
+
7402
+ for co in tones_chord_combs:
7403
+ if co in CHORDS:
7404
+ tones_chord = co
7405
+ break
7406
+
7407
+ new_pitches_chord = []
7408
+
7409
+ for p in pitches_chord:
7410
+
7411
+ if p % 12 in tones_chord:
7412
+ new_pitches_chord.append(p)
7413
+
7414
+ return sorted(new_pitches_chord, reverse=True)
7415
+
7416
+ ###################################################################################
7417
+
7418
+ ALL_CHORDS_TRANS = [[0], [0, 4], [0, 4, 7], [0, 4, 8], [0, 5], [0, 6], [0, 7], [0, 8], [1], [1, 5],
7419
+ [1, 5, 9], [1, 6], [1, 7], [1, 8], [1, 9], [2], [2, 6], [2, 6, 10], [2, 7],
7420
+ [2, 8], [2, 9], [2, 10], [3], [3, 7], [3, 7, 11], [3, 8], [3, 9], [3, 10],
7421
+ [3, 11], [4], [4, 7], [4, 7, 11], [4, 8], [4, 9], [4, 10], [4, 11], [5],
7422
+ [5, 9], [5, 10], [5, 11], [6], [6, 10], [6, 11], [7], [7, 11], [8], [9], [10],
7423
+ [11]]
7424
+
7425
+ ###################################################################################
7426
+
7427
+ def minkowski_distance(x, y, p=3, pad_value=float('inf')):
7428
+
7429
+ if len(x) != len(y):
7430
+ return -1
7431
+
7432
+ distance = 0
7433
+
7434
+ for i in range(len(x)):
7435
+
7436
+ if x[i] == pad_value or y[i] == pad_value:
7437
+ continue
7438
+
7439
+ distance += abs(x[i] - y[i]) ** p
7440
+
7441
+ return distance ** (1 / p)
7442
+
7443
+ ###################################################################################
7444
+
7445
+ def dot_product(x, y, pad_value=None):
7446
+ return sum(xi * yi for xi, yi in zip(x, y) if xi != pad_value and yi != pad_value)
7447
+
7448
+ def norm(vector, pad_value=None):
7449
+ return sum(xi ** 2 for xi in vector if xi != pad_value) ** 0.5
7450
+
7451
+ def cosine_similarity(x, y, pad_value=None):
7452
+ if len(x) != len(y):
7453
+ return -1
7454
+
7455
+ dot_prod = dot_product(x, y, pad_value)
7456
+ norm_x = norm(x, pad_value)
7457
+ norm_y = norm(y, pad_value)
7458
+
7459
+ if norm_x == 0 or norm_y == 0:
7460
+ return 0.0
7461
+
7462
+ return dot_prod / (norm_x * norm_y)
7463
+
7464
+ ###################################################################################
7465
+
7466
+ def hamming_distance(arr1, arr2, pad_value):
7467
+ return sum(el1 != el2 for el1, el2 in zip(arr1, arr2) if el1 != pad_value and el2 != pad_value)
7468
+
7469
+ ###################################################################################
7470
+
7471
+ def jaccard_similarity(arr1, arr2, pad_value):
7472
+ intersection = sum(el1 and el2 for el1, el2 in zip(arr1, arr2) if el1 != pad_value and el2 != pad_value)
7473
+ union = sum((el1 or el2) for el1, el2 in zip(arr1, arr2) if el1 != pad_value or el2 != pad_value)
7474
+ return intersection / union if union != 0 else 0
7475
+
7476
+ ###################################################################################
7477
+
7478
+ def pearson_correlation(arr1, arr2, pad_value):
7479
+ filtered_pairs = [(el1, el2) for el1, el2 in zip(arr1, arr2) if el1 != pad_value and el2 != pad_value]
7480
+ if not filtered_pairs:
7481
+ return 0
7482
+ n = len(filtered_pairs)
7483
+ sum1 = sum(el1 for el1, el2 in filtered_pairs)
7484
+ sum2 = sum(el2 for el1, el2 in filtered_pairs)
7485
+ sum1_sq = sum(el1 ** 2 for el1, el2 in filtered_pairs)
7486
+ sum2_sq = sum(el2 ** 2 for el1, el2 in filtered_pairs)
7487
+ p_sum = sum(el1 * el2 for el1, el2 in filtered_pairs)
7488
+ num = p_sum - (sum1 * sum2 / n)
7489
+ den = ((sum1_sq - sum1 ** 2 / n) * (sum2_sq - sum2 ** 2 / n)) ** 0.5
7490
+ if den == 0:
7491
+ return 0
7492
+ return num / den
7493
+
7494
+ ###################################################################################
7495
+
7496
+ def calculate_combined_distances(array_of_arrays,
7497
+ combine_hamming_distance=True,
7498
+ combine_jaccard_similarity=True,
7499
+ combine_pearson_correlation=True,
7500
+ pad_value=None
7501
+ ):
7502
+
7503
+ binary_arrays = array_of_arrays
7504
+ binary_array_len = len(binary_arrays)
7505
+
7506
+ hamming_distances = [[0] * binary_array_len for _ in range(binary_array_len)]
7507
+ jaccard_similarities = [[0] * binary_array_len for _ in range(binary_array_len)]
7508
+ pearson_correlations = [[0] * binary_array_len for _ in range(binary_array_len)]
7509
+
7510
+ for i in range(binary_array_len):
7511
+ for j in range(i + 1, binary_array_len):
7512
+ hamming_distances[i][j] = hamming_distance(binary_arrays[i], binary_arrays[j], pad_value)
7513
+ hamming_distances[j][i] = hamming_distances[i][j]
7514
+
7515
+ jaccard_similarities[i][j] = jaccard_similarity(binary_arrays[i], binary_arrays[j], pad_value)
7516
+ jaccard_similarities[j][i] = jaccard_similarities[i][j]
7517
+
7518
+ pearson_correlations[i][j] = pearson_correlation(binary_arrays[i], binary_arrays[j], pad_value)
7519
+ pearson_correlations[j][i] = pearson_correlations[i][j]
7520
+
7521
+ max_hamming = max(max(row) for row in hamming_distances)
7522
+ min_hamming = min(min(row) for row in hamming_distances)
7523
+ normalized_hamming = [[(val - min_hamming) / (max_hamming - min_hamming) for val in row] for row in hamming_distances]
7524
+
7525
+ max_jaccard = max(max(row) for row in jaccard_similarities)
7526
+ min_jaccard = min(min(row) for row in jaccard_similarities)
7527
+ normalized_jaccard = [[(val - min_jaccard) / (max_jaccard - min_jaccard) for val in row] for row in jaccard_similarities]
7528
+
7529
+ max_pearson = max(max(row) for row in pearson_correlations)
7530
+ min_pearson = min(min(row) for row in pearson_correlations)
7531
+ normalized_pearson = [[(val - min_pearson) / (max_pearson - min_pearson) for val in row] for row in pearson_correlations]
7532
+
7533
+ selected_metrics = 0
7534
+
7535
+ if combine_hamming_distance:
7536
+ selected_metrics += normalized_hamming[i][j]
7537
+
7538
+ if combine_jaccard_similarity:
7539
+ selected_metrics += (1 - normalized_jaccard[i][j])
7540
+
7541
+ if combine_pearson_correlation:
7542
+ selected_metrics += (1 - normalized_pearson[i][j])
7543
+
7544
+ combined_metric = [[selected_metrics for i in range(binary_array_len)] for j in range(binary_array_len)]
7545
+
7546
+ return combined_metric
7547
+
7548
+ ###################################################################################
7549
+
7550
+ def tones_chords_to_bits(tones_chords):
7551
+
7552
+ bits_tones_chords = []
7553
+
7554
+ for c in tones_chords:
7555
+
7556
+ c.sort()
7557
+
7558
+ bits = tones_chord_to_bits(c)
7559
+
7560
+ bits_tones_chords.append(bits)
7561
+
7562
+ return bits_tones_chords
7563
+
7564
+ ###################################################################################
7565
+
7566
+ def tones_chords_to_ints(tones_chords):
7567
+
7568
+ ints_tones_chords = []
7569
+
7570
+ for c in tones_chords:
7571
+
7572
+ c.sort()
7573
+
7574
+ bits = tones_chord_to_bits(c)
7575
+
7576
+ number = bits_to_int(bits)
7577
+
7578
+ ints_tones_chords.append(number)
7579
+
7580
+ return ints_tones_chords
7581
+
7582
+ ###################################################################################
7583
+
7584
+ def tones_chords_to_types(tones_chords,
7585
+ return_chord_type_index=False
7586
+ ):
7587
+
7588
+ types_tones_chords = []
7589
+
7590
+ for c in tones_chords:
7591
+
7592
+ c.sort()
7593
+
7594
+ ctype = tones_chord_type(c, return_chord_type_index=return_chord_type_index)
7595
+
7596
+ types_tones_chords.append(ctype)
7597
+
7598
+ return types_tones_chords
7599
+
7600
+ ###################################################################################
7601
+
7602
+ def morph_tones_chord(tones_chord,
7603
+ trg_tone,
7604
+ use_filtered_chords=True
7605
+ ):
7606
+
7607
+ src_tones_chord = sorted(sorted(set(tones_chord)) + [trg_tone])
7608
+
7609
+ 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)]
7610
+
7611
+ matches = []
7612
+
7613
+ if use_filtered_chords:
7614
+ CHORDS = ALL_CHORDS_FILTERED
7615
+
7616
+ else:
7617
+ CHORDS = ALL_CHORDS_SORTED
7618
+
7619
+ for c in combs:
7620
+ if sorted(set(c)) in CHORDS:
7621
+ matches.append(sorted(set(c)))
7622
+
7623
+ max_len = len(max(matches, key=len))
7624
+
7625
+ return random.choice([m for m in matches if len(m) == max_len])
7626
+
7627
+ ###################################################################################
7628
+
7629
+ def compress_binary_matrix(binary_matrix,
7630
+ only_compress_zeros=False,
7631
+ return_compression_ratio=False
7632
+ ):
7633
+
7634
+ compressed_bmatrix = []
7635
+
7636
+ zm = [0] * len(binary_matrix[0])
7637
+ pm = [0] * len(binary_matrix[0])
7638
+
7639
+ mcount = 0
7640
+
7641
+ for m in binary_matrix:
7642
+
7643
+ if only_compress_zeros:
7644
+ if m != zm:
7645
+ compressed_bmatrix.append(m)
7646
+ mcount += 1
7647
+
7648
+ else:
7649
+ if m != pm:
7650
+ compressed_bmatrix.append(m)
7651
+ mcount += 1
7652
+
7653
+ pm = m
7654
+
7655
+ if return_compression_ratio:
7656
+ return [compressed_bmatrix, mcount / len(binary_matrix)]
7657
+
7658
+ else:
7659
+ return compressed_bmatrix
7660
+
7661
+ ###################################################################################
7662
+
7663
+ def solo_piano_escore_notes(escore_notes,
7664
+ channels_index=3,
7665
+ pitches_index=4,
7666
+ patches_index=6,
7667
+ keep_drums=False,
7668
+ ):
7669
+
7670
+ cscore = chordify_score([1000, escore_notes])
7671
+
7672
+ sp_escore_notes = []
7673
+
7674
+ for c in cscore:
7675
+
7676
+ seen = []
7677
+ chord = []
7678
+
7679
+ for cc in c:
7680
+ if cc[pitches_index] not in seen:
7681
+
7682
+ if cc[channels_index] != 9:
7683
+ cc[channels_index] = 0
7684
+ cc[patches_index] = 0
7685
+
7686
+ chord.append(cc)
7687
+ seen.append(cc[pitches_index])
7688
+
7689
+ else:
7690
+ if keep_drums:
7691
+ chord.append(cc)
7692
+ seen.append(cc[pitches_index])
7693
+
7694
+ sp_escore_notes.append(chord)
7695
+
7696
+ return flatten(sp_escore_notes)
7697
+
7698
+ ###################################################################################
7699
+
7700
+ def strip_drums_from_escore_notes(escore_notes,
7701
+ channels_index=3
7702
+ ):
7703
+
7704
+ return [e for e in escore_notes if e[channels_index] != 9]
7705
+
7706
+ ###################################################################################
7707
+
7708
+ def fixed_escore_notes_timings(escore_notes,
7709
+ fixed_durations=False,
7710
+ fixed_timings_multiplier=1,
7711
+ custom_fixed_time=-1,
7712
+ custom_fixed_dur=-1
7713
+ ):
7714
+
7715
+ fixed_timings_escore_notes = delta_score_notes(escore_notes, even_timings=True)
7716
+
7717
+ mode_time = round(Counter([e[1] for e in fixed_timings_escore_notes if e[1] != 0]).most_common()[0][0] * fixed_timings_multiplier)
7718
+
7719
+ if mode_time % 2 != 0:
7720
+ mode_time += 1
7721
+
7722
+ mode_dur = round(Counter([e[2] for e in fixed_timings_escore_notes if e[2] != 0]).most_common()[0][0] * fixed_timings_multiplier)
7723
+
7724
+ if mode_dur % 2 != 0:
7725
+ mode_dur += 1
7726
+
7727
+ for e in fixed_timings_escore_notes:
7728
+ if e[1] != 0:
7729
+
7730
+ if custom_fixed_time > 0:
7731
+ e[1] = custom_fixed_time
7732
+
7733
+ else:
7734
+ e[1] = mode_time
7735
+
7736
+ if fixed_durations:
7737
+
7738
+ if custom_fixed_dur > 0:
7739
+ e[2] = custom_fixed_dur
7740
+
7741
+ else:
7742
+ e[2] = mode_dur
7743
+
7744
+ return delta_score_to_abs_score(fixed_timings_escore_notes)
7745
+
7746
+ ###################################################################################
7747
+
7748
+ def cubic_kernel(x):
7749
+ abs_x = abs(x)
7750
+ if abs_x <= 1:
7751
+ return (1.5 * abs_x**3 - 2.5 * abs_x**2 + 1)
7752
+ elif abs_x <= 2:
7753
+ return (-0.5 * abs_x**3 + 2.5 * abs_x**2 - 4 * abs_x + 2)
7754
+ else:
7755
+ return 0
7756
+
7757
+ ###################################################################################
7758
+
7759
+ def resize_matrix(matrix, new_height, new_width):
7760
+ old_height = len(matrix)
7761
+ old_width = len(matrix[0])
7762
+ resized_matrix = [[0] * new_width for _ in range(new_height)]
7763
+
7764
+ for i in range(new_height):
7765
+ for j in range(new_width):
7766
+
7767
+ old_i = i * old_height / new_height
7768
+ old_j = j * old_width / new_width
7769
+
7770
+ value = 0
7771
+ for m in range(-1, 3):
7772
+ for n in range(-1, 3):
7773
+ i_m = min(max(int(old_i) + m, 0), old_height - 1)
7774
+ j_n = min(max(int(old_j) + n, 0), old_width - 1)
7775
+ weight = cubic_kernel(old_i - i_m) * cubic_kernel(old_j - j_n)
7776
+ value += matrix[i_m][j_n] * weight
7777
+
7778
+ resized_matrix[i][j] = int(value > 0.5)
7779
+
7780
+ return resized_matrix
7781
+
7782
+ ###################################################################################
7783
+
7784
+ def square_binary_matrix(binary_matrix,
7785
+ matrix_size=128,
7786
+ use_fast_squaring=False,
7787
+ return_plot_points=False
7788
+ ):
7789
+
7790
+ if use_fast_squaring:
7791
+
7792
+ step = round(len(binary_matrix) / matrix_size)
7793
+
7794
+ samples = []
7795
+
7796
+ for i in range(0, len(binary_matrix), step):
7797
+ samples.append(tuple([tuple(d) for d in binary_matrix[i:i+step]]))
7798
+
7799
+ resized_matrix = []
7800
+
7801
+ zmatrix = [[0] * matrix_size]
7802
+
7803
+ for s in samples:
7804
+
7805
+ samples_counts = Counter(s).most_common()
7806
+
7807
+ best_sample = tuple([0] * matrix_size)
7808
+ pm = tuple(zmatrix[0])
7809
+
7810
+ for sc in samples_counts:
7811
+ if sc[0] != tuple(zmatrix[0]) and sc[0] != pm:
7812
+ best_sample = sc[0]
7813
+ pm = sc[0]
7814
+ break
7815
+
7816
+ pm = sc[0]
7817
+
7818
+ resized_matrix.append(list(best_sample))
7819
+
7820
+ resized_matrix = resized_matrix[:matrix_size]
7821
+ resized_matrix += zmatrix * (matrix_size - len(resized_matrix))
7822
+
7823
+ else:
7824
+ resized_matrix = resize_matrix(binary_matrix, matrix_size, matrix_size)
7825
+
7826
+ points = [(i, j) for i in range(matrix_size) for j in range(matrix_size) if resized_matrix[i][j] == 1]
7827
+
7828
+ if return_plot_points:
7829
+ return [resized_matrix, points]
7830
+
7831
+ else:
7832
+ return resized_matrix
7833
+
7834
+ ###################################################################################
7835
+
7836
+ def mean(matrix):
7837
+ return sum(sum(row) for row in matrix) / (len(matrix) * len(matrix[0]))
7838
+
7839
+ ###################################################################################
7840
+
7841
+ def variance(matrix, mean_value):
7842
+ return sum(sum((element - mean_value) ** 2 for element in row) for row in matrix) / (len(matrix) * len(matrix[0]))
7843
+
7844
+ ###################################################################################
7845
+
7846
+ def covariance(matrix1, matrix2, mean1, mean2):
7847
+ 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]))
7848
+
7849
+ ###################################################################################
7850
+
7851
+ def ssim_index(matrix1, matrix2, bit_depth=1):
7852
+
7853
+ if len(matrix1) != len(matrix2) and len(matrix1[0]) != len(matrix2[0]):
7854
+ return -1
7855
+
7856
+ K1, K2 = 0.01, 0.03
7857
+ L = bit_depth
7858
+ C1 = (K1 * L) ** 2
7859
+ C2 = (K2 * L) ** 2
7860
+
7861
+ mu1 = mean(matrix1)
7862
+ mu2 = mean(matrix2)
7863
+
7864
+ sigma1_sq = variance(matrix1, mu1)
7865
+ sigma2_sq = variance(matrix2, mu2)
7866
+
7867
+ sigma12 = covariance(matrix1, matrix2, mu1, mu2)
7868
+
7869
+ ssim = ((2 * mu1 * mu2 + C1) * (2 * sigma12 + C2)) / ((mu1 ** 2 + mu2 ** 2 + C1) * (sigma1_sq + sigma2_sq + C2))
7870
+
7871
+ return ssim
7872
+
7873
+ ###################################################################################
7874
+
7875
+ def find_most_similar_matrix(array_of_matrices,
7876
+ trg_matrix,
7877
+ matrices_bit_depth=1,
7878
+ return_most_similar_index=False
7879
+ ):
7880
+
7881
+ max_ssim = -float('inf')
7882
+ most_similar_index = -1
7883
+
7884
+ for i, matrix in enumerate(array_of_matrices):
7885
+
7886
+ ssim = ssim_index(matrix, trg_matrix, bit_depth=matrices_bit_depth)
7887
+
7888
+ if ssim > max_ssim:
7889
+ max_ssim = ssim
7890
+ most_similar_index = i
7891
+
7892
+ if return_most_similar_index:
7893
+ return most_similar_index
7894
+
7895
+ else:
7896
+ return array_of_matrices[most_similar_index]
7897
+
7898
+ ###################################################################################
7899
+
7900
+ def chord_to_pchord(chord):
7901
+
7902
+ pchord = []
7903
+
7904
+ for cc in chord:
7905
+ if cc[3] != 9:
7906
+ pchord.append(cc[4])
7907
+ else:
7908
+ pchord.append(cc[4]+128)
7909
+
7910
+ return pchord
7911
+
7912
+ def summarize_escore_notes(escore_notes,
7913
+ summary_length_in_chords=128,
7914
+ preserve_timings=True
7915
+ ):
7916
+
7917
+ cscore = chordify_score([d[1:] for d in delta_score_notes(escore_notes)])
7918
+
7919
+ pchords = []
7920
+
7921
+ for c in cscore:
7922
+ pchords.append(chord_to_pchord(c))
7923
+
7924
+ step = round(len(pchords) / summary_length_in_chords)
7925
+
7926
+ samples = []
7927
+
7928
+ for i in range(0, len(pchords), step):
7929
+ samples.append(tuple([tuple(d) for d in pchords[i:i+step]]))
7930
+
7931
+ summarized_escore_notes = []
7932
+
7933
+ for i, s in enumerate(samples):
7934
+
7935
+ best_chord = list(Counter(s).most_common()[0][0])
7936
+
7937
+ chord = copy.deepcopy(cscore[[list(ss) for ss in s].index(best_chord)+(i*step)])
7938
+
7939
+ if preserve_timings:
7940
+
7941
+ if i > 0:
7942
+
7943
+ pchord = summarized_escore_notes[-1]
7944
+
7945
+ for c in pchord:
7946
+ c[1] = max(c[1], chord[0][0])
7947
+
7948
+ else:
7949
+
7950
+ chord[0][0] = 1
7951
+
7952
+ for c in chord:
7953
+ c[1] = 1
7954
+
7955
+ summarized_escore_notes.append(chord)
7956
+
7957
+ summarized_escore_notes = summarized_escore_notes[:summary_length_in_chords]
7958
+
7959
+ return [['note'] + d for d in delta_score_to_abs_score(flatten(summarized_escore_notes), times_idx=0)]
7960
+
7961
+ ###################################################################################
7962
+
7963
  # This is the end of the TMIDI X Python module
7964
 
7965
  ###################################################################################