asigalov61 commited on
Commit
f26e052
1 Parent(s): 37b7b73

Upload 2 files

Browse files
Files changed (2) hide show
  1. TMIDIX.py +809 -132
  2. TPLOTS.py +143 -19
TMIDIX.py CHANGED
@@ -471,19 +471,6 @@ def grep(score=None, channels=None):
471
  itrack += 1
472
  return new_score
473
 
474
- def play_score(score=None):
475
- r'''Converts the "score" to midi, and feeds it into 'aplaymidi -'
476
- '''
477
- if score == None:
478
- return
479
- import subprocess
480
- pipe = subprocess.Popen(['aplaymidi','-'], stdin=subprocess.PIPE)
481
- if score_type(score) == 'opus':
482
- pipe.stdin.write(opus2midi(score))
483
- else:
484
- pipe.stdin.write(score2midi(score))
485
- pipe.stdin.close()
486
-
487
  def score2stats(opus_or_score=None):
488
  r'''Returns a dict of some basic stats about the score, like
489
  bank_select (list of tuples (msb,lsb)),
@@ -1832,6 +1819,7 @@ def plot_ms_SONG(ms_song,
1832
  plt.close()
1833
 
1834
  if return_plt:
 
1835
  return fig
1836
 
1837
  plt.show()
@@ -2059,7 +2047,7 @@ def Optimus_MIDI_TXT_Processor(MIDI_file,
2059
 
2060
  #print('Loading MIDI file...')
2061
  midi_file = open(MIDI_file, 'rb')
2062
- if debug: print('Processing File:', file_address)
2063
 
2064
  try:
2065
  opus = midi2opus(midi_file.read())
@@ -4608,88 +4596,48 @@ def ascii_text_words_counter(ascii_text):
4608
 
4609
  ###################################################################################
4610
 
4611
- def check_and_fix_tones_chord(tones_chord):
4612
-
4613
- lst = tones_chord
4614
 
4615
- if len(lst) == 2:
4616
- if lst[1] - lst[0] == 1:
4617
- return [lst[-1]]
4618
- else:
4619
- if 0 in lst and 11 in lst:
4620
- lst.remove(0)
4621
- return lst
4622
 
4623
- non_consecutive = [lst[0]]
 
4624
 
4625
- if len(lst) > 2:
4626
- for i in range(1, len(lst) - 1):
4627
- if lst[i-1] + 1 != lst[i] and lst[i] + 1 != lst[i+1]:
4628
- non_consecutive.append(lst[i])
4629
- non_consecutive.append(lst[-1])
4630
 
4631
- if 0 in non_consecutive and 11 in non_consecutive:
4632
- non_consecutive.remove(0)
 
 
4633
 
4634
- return non_consecutive
4635
 
4636
  ###################################################################################
4637
 
4638
  def find_closest_tone(tones, tone):
4639
  return min(tones, key=lambda x:abs(x-tone))
4640
 
4641
- def advanced_check_and_fix_tones_chord(tones_chord, high_pitch=0):
4642
 
4643
- lst = tones_chord
4644
 
4645
- if 0 < high_pitch < 128:
4646
- ht = high_pitch % 12
4647
- else:
4648
- ht = 12
4649
 
4650
- cht = find_closest_tone(lst, ht)
 
4651
 
4652
- if len(lst) == 2:
4653
- if lst[1] - lst[0] == 1:
4654
- return [cht]
4655
- else:
4656
- if 0 in lst and 11 in lst:
4657
- if find_closest_tone([0, 11], cht) == 11:
4658
- lst.remove(0)
4659
- else:
4660
- lst.remove(11)
4661
- return lst
4662
-
4663
- non_consecutive = []
4664
-
4665
- if len(lst) > 2:
4666
- for i in range(0, len(lst) - 1):
4667
- if lst[i] + 1 != lst[i+1]:
4668
- non_consecutive.append(lst[i])
4669
- if lst[-1] - lst[-2] > 1:
4670
- non_consecutive.append(lst[-1])
4671
-
4672
- if cht not in non_consecutive:
4673
- non_consecutive.append(cht)
4674
- non_consecutive.sort()
4675
- if any(abs(non_consecutive[i+1] - non_consecutive[i]) == 1 for i in range(len(non_consecutive) - 1)):
4676
- final_list = [x for x in non_consecutive if x == cht or abs(x - cht) > 1]
4677
- else:
4678
- final_list = non_consecutive
4679
 
4680
- else:
4681
- final_list = non_consecutive
 
4682
 
4683
- if 0 in final_list and 11 in final_list:
4684
- if find_closest_tone([0, 11], cht) == 11:
4685
- final_list.remove(0)
4686
- else:
4687
- final_list.remove(11)
4688
 
4689
- if cht in final_list or ht in final_list:
4690
- return final_list
4691
- else:
4692
- return ['Error']
4693
 
4694
  ###################################################################################
4695
 
@@ -4727,7 +4675,9 @@ def augment_enhanced_score_notes(enhanced_score_notes,
4727
  full_sorting=True,
4728
  timings_shift=0,
4729
  pitch_shift=0,
4730
- legacy_timings=False
 
 
4731
  ):
4732
 
4733
  esn = copy.deepcopy(enhanced_score_notes)
@@ -4740,11 +4690,15 @@ def augment_enhanced_score_notes(enhanced_score_notes,
4740
 
4741
  dtime = (e[1] / timings_divider) - (pe[1] / timings_divider)
4742
 
4743
- if 0.5 < dtime < 1:
4744
- dtime = 1
4745
 
4746
  else:
4747
- dtime = int(dtime)
 
 
 
 
4748
 
4749
  if legacy_timings:
4750
  abs_time = int(e[1] / timings_divider) + timings_shift
@@ -4754,7 +4708,14 @@ def augment_enhanced_score_notes(enhanced_score_notes,
4754
 
4755
  e[1] = max(0, abs_time + timings_shift)
4756
 
4757
- e[2] = max(1, int(e[2] / timings_divider)) + timings_shift
 
 
 
 
 
 
 
4758
 
4759
  e[4] = max(1, min(127, e[4] + pitch_shift))
4760
 
@@ -5204,8 +5165,11 @@ def advanced_check_and_fix_chords_in_chordified_score(chordified_score,
5204
  channels_index=3,
5205
  pitches_index=4,
5206
  patches_index=6,
5207
- use_filtered_chords=True,
 
5208
  remove_duplicate_pitches=True,
 
 
5209
  skip_drums=False
5210
  ):
5211
  fixed_chordified_score = []
@@ -5218,16 +5182,21 @@ def advanced_check_and_fix_chords_in_chordified_score(chordified_score,
5218
  else:
5219
  CHORDS = ALL_CHORDS_SORTED
5220
 
 
 
 
5221
  for c in chordified_score:
5222
 
 
 
5223
  if remove_duplicate_pitches:
5224
 
5225
- c.sort(key = lambda x: x[pitches_index], reverse=True)
5226
 
5227
  seen = set()
5228
  ddchord = []
5229
 
5230
- for cc in c:
5231
  if cc[channels_index] != 9:
5232
 
5233
  if tuple([cc[pitches_index], cc[patches_index]]) not in seen:
@@ -5239,9 +5208,9 @@ def advanced_check_and_fix_chords_in_chordified_score(chordified_score,
5239
  else:
5240
  ddchord.append(cc)
5241
 
5242
- c = copy.deepcopy(ddchord)
5243
 
5244
- tones_chord = sorted(set([t[pitches_index] % 12 for t in c if t[channels_index] != 9]))
5245
 
5246
  if tones_chord:
5247
 
@@ -5253,34 +5222,127 @@ def advanced_check_and_fix_chords_in_chordified_score(chordified_score,
5253
  tones_counts = Counter([p % 12 for p in pitches_chord]).most_common()
5254
 
5255
  if tones_counts[0][1] > 1:
5256
- tones_chord = [tones_counts[0][0]]
 
 
5257
  elif tones_counts[1][1] > 1:
5258
- tones_chord = [tones_counts[1][0]]
 
 
5259
  else:
5260
- tones_chord = [pitches_chord[0] % 12]
 
5261
 
5262
- else:
5263
- tones_chord_combs = [list(comb) for i in range(len(tones_chord)-2, 0, -1) for comb in combinations(tones_chord, i+1)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5264
 
5265
  for co in tones_chord_combs:
5266
  if co in CHORDS:
5267
- tones_chord = co
5268
  break
5269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5270
  bad_chords_counter += 1
5271
 
5272
- new_chord = []
5273
 
5274
- c.sort(key = lambda x: x[pitches_index], reverse=True)
 
5275
 
5276
- for e in c:
5277
  if e[channels_index] != 9:
5278
  if e[pitches_index] % 12 in tones_chord:
5279
- new_chord.append(e)
 
5280
 
5281
- else:
5282
- if not skip_drums:
5283
- new_chord.append(e)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5284
 
5285
  fixed_chordified_score.append(new_chord)
5286
 
@@ -5476,11 +5538,11 @@ def harmonize_enhanced_melody_score_notes(enhanced_melody_score_notes):
5476
  cur_chord.append(m)
5477
  cc = sorted(set(cur_chord))
5478
 
5479
- if cc in ALL_CHORDS_FILTERED:
5480
  song.append(cc)
5481
 
5482
  else:
5483
- while sorted(set(cur_chord)) not in ALL_CHORDS_FILTERED:
5484
  cur_chord.pop(0)
5485
  cc = sorted(set(cur_chord))
5486
  song.append(cc)
@@ -5617,7 +5679,7 @@ def basic_enhanced_delta_score_notes_tokenizer(enhanced_delta_score_notes,
5617
  final_score_tokens_ints_seq = flatten(score_tokens_ints_seq)
5618
 
5619
  if max_seq_len > -1:
5620
- final_score_tokens_ints_seq = flat_score_tokens_ints_seq[:max_seq_len]
5621
 
5622
  if seq_pad_value > -1:
5623
  final_score_tokens_ints_seq += [seq_pad_value] * (max_seq_len - len(final_score_tokens_ints_seq))
@@ -5680,7 +5742,8 @@ def basic_enhanced_delta_score_notes_detokenizer(tokenized_seq,
5680
  def enhanced_chord_to_chord_token(enhanced_chord,
5681
  channels_index=3,
5682
  pitches_index=4,
5683
- use_filtered_chords=True
 
5684
  ):
5685
 
5686
  bad_chords_counter = 0
@@ -5691,6 +5754,9 @@ def enhanced_chord_to_chord_token(enhanced_chord,
5691
  else:
5692
  CHORDS = ALL_CHORDS_SORTED
5693
 
 
 
 
5694
  tones_chord = sorted(set([t[pitches_index] % 12 for t in enhanced_chord if t[channels_index] != 9]))
5695
 
5696
  original_tones_chord = copy.deepcopy(tones_chord)
@@ -7134,7 +7200,8 @@ CHORDS_TYPES = ['WHITE', 'BLACK', 'UNKNOWN', 'MIXED WHITE', 'MIXED BLACK', 'MIXE
7134
 
7135
  def tones_chord_type(tones_chord,
7136
  return_chord_type_index=True,
7137
- use_filtered_chords=True
 
7138
  ):
7139
 
7140
  WN = WHITE_NOTES
@@ -7147,6 +7214,9 @@ def tones_chord_type(tones_chord,
7147
  else:
7148
  CHORDS = ALL_CHORDS_SORTED
7149
 
 
 
 
7150
  tones_chord = sorted(tones_chord)
7151
 
7152
  ctype = 'UNKNOWN'
@@ -7237,7 +7307,8 @@ def find_best_tones_chord(src_tones_chords,
7237
  def find_matching_tones_chords(tones_chord,
7238
  matching_chord_length=-1,
7239
  match_chord_type=True,
7240
- use_filtered_chords=True
 
7241
  ):
7242
 
7243
  if use_filtered_chords:
@@ -7245,6 +7316,9 @@ def find_matching_tones_chords(tones_chord,
7245
  else:
7246
  CHORDS = ALL_CHORDS_SORTED
7247
 
 
 
 
7248
  tones_chord = sorted(tones_chord)
7249
 
7250
  tclen = len(tones_chord)
@@ -7427,46 +7501,104 @@ def harmonize_enhanced_melody_score_notes_to_ms_SONG(escore_notes,
7427
  ###################################################################################
7428
 
7429
  def check_and_fix_pitches_chord(pitches_chord,
7430
- use_filtered_chords=True
 
 
 
7431
  ):
7432
 
7433
- pitches_chord = sorted(pitches_chord, reverse=True)
 
 
 
7434
 
7435
  if use_filtered_chords:
7436
  CHORDS = ALL_CHORDS_FILTERED
7437
  else:
7438
  CHORDS = ALL_CHORDS_SORTED
7439
 
7440
- tones_chord = sorted(set([p % 12 for p in pitches_chord]))
 
7441
 
7442
- if tones_chord not in CHORDS:
 
 
 
 
7443
 
7444
- if len(tones_chord) == 2:
 
 
 
7445
 
7446
- tones_counts = Counter([p % 12 for p in pitches_chord]).most_common()
 
 
 
 
 
 
 
7447
 
7448
- if tones_counts[0][1] > 1:
7449
- tones_chord = [tones_counts[0][0]]
7450
- elif tones_counts[1][1] > 1:
7451
- tones_chord = [tones_counts[1][0]]
7452
- else:
7453
- tones_chord = [pitches_chord[0] % 12]
 
7454
 
7455
- if len(tones_chord) > 2:
 
 
 
7456
 
7457
- tones_chord_combs = [list(comb) for i in range(len(tones_chord)-2, 0, -1) for comb in combinations(tones_chord, i+1)]
 
7458
 
7459
- for co in tones_chord_combs:
7460
- if co in CHORDS:
7461
- tones_chord = co
7462
- break
7463
 
7464
- new_pitches_chord = []
 
 
 
7465
 
7466
- for p in pitches_chord:
 
 
 
7467
 
7468
- if p % 12 in tones_chord:
7469
- new_pitches_chord.append(p)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7470
 
7471
  return sorted(new_pitches_chord, reverse=True)
7472
 
@@ -7658,7 +7790,8 @@ def tones_chords_to_types(tones_chords,
7658
 
7659
  def morph_tones_chord(tones_chord,
7660
  trg_tone,
7661
- use_filtered_chords=True
 
7662
  ):
7663
 
7664
  src_tones_chord = sorted(sorted(set(tones_chord)) + [trg_tone])
@@ -7673,6 +7806,9 @@ def morph_tones_chord(tones_chord,
7673
  else:
7674
  CHORDS = ALL_CHORDS_SORTED
7675
 
 
 
 
7676
  for c in combs:
7677
  if sorted(set(c)) in CHORDS:
7678
  matches.append(sorted(set(c)))
@@ -8061,7 +8197,7 @@ def compress_patches_in_escore_notes(escore_notes,
8061
  n_patches = num_patches
8062
 
8063
  if group_patches:
8064
- patches_set = sorted(set([e[6] for e in c]))
8065
  trg_patch_list = []
8066
  seen = []
8067
  for p in patches_set:
@@ -8072,7 +8208,7 @@ def compress_patches_in_escore_notes(escore_notes,
8072
  trg_patch_list = sorted(trg_patch_list)
8073
 
8074
  else:
8075
- trg_patch_list = sorted(set([e[6] for e in c]))
8076
 
8077
  if 128 in trg_patch_list and n_patches > 1:
8078
  trg_patch_list = trg_patch_list[:n_patches-1] + [128]
@@ -8423,6 +8559,547 @@ def proportions_counter(list_of_values):
8423
 
8424
  return [[c[0], c[1], c[1] / clen] for c in counts]
8425
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8426
  ###################################################################################
8427
  #
8428
  # This is the end of the TMIDI X Python module
 
471
  itrack += 1
472
  return new_score
473
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
  def score2stats(opus_or_score=None):
475
  r'''Returns a dict of some basic stats about the score, like
476
  bank_select (list of tuples (msb,lsb)),
 
1819
  plt.close()
1820
 
1821
  if return_plt:
1822
+ plt.close(fig)
1823
  return fig
1824
 
1825
  plt.show()
 
2047
 
2048
  #print('Loading MIDI file...')
2049
  midi_file = open(MIDI_file, 'rb')
2050
+ if debug: print('Processing File:', MIDI_file)
2051
 
2052
  try:
2053
  opus = midi2opus(midi_file.read())
 
4596
 
4597
  ###################################################################################
4598
 
4599
+ def check_and_fix_tones_chord(tones_chord, use_full_chords=True):
 
 
4600
 
4601
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord), 0, -1) for comb in combinations(tones_chord, i)]
 
 
 
 
 
 
4602
 
4603
+ if use_full_chords:
4604
+ CHORDS = ALL_CHORDS_FULL
4605
 
4606
+ else:
4607
+ CHORDS = ALL_CHORDS_SORTED
 
 
 
4608
 
4609
+ for c in tones_chord_combs:
4610
+ if c in CHORDS:
4611
+ checked_tones_chord = c
4612
+ break
4613
 
4614
+ return sorted(checked_tones_chord)
4615
 
4616
  ###################################################################################
4617
 
4618
  def find_closest_tone(tones, tone):
4619
  return min(tones, key=lambda x:abs(x-tone))
4620
 
4621
+ ###################################################################################
4622
 
4623
+ def advanced_check_and_fix_tones_chord(tones_chord, high_pitch=0, use_full_chords=True):
4624
 
4625
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord), 0, -1) for comb in combinations(tones_chord, i)]
 
 
 
4626
 
4627
+ if use_full_chords:
4628
+ CHORDS = ALL_CHORDS_FULL
4629
 
4630
+ else:
4631
+ CHORDS = ALL_CHORDS_SORTED
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4632
 
4633
+ for c in tones_chord_combs:
4634
+ if c in CHORDS:
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
 
 
4675
  full_sorting=True,
4676
  timings_shift=0,
4677
  pitch_shift=0,
4678
+ ceil_timings=False,
4679
+ round_timings=False,
4680
+ legacy_timings=True
4681
  ):
4682
 
4683
  esn = copy.deepcopy(enhanced_score_notes)
 
4690
 
4691
  dtime = (e[1] / timings_divider) - (pe[1] / timings_divider)
4692
 
4693
+ if round_timings:
4694
+ dtime = round(dtime)
4695
 
4696
  else:
4697
+ if ceil_timings:
4698
+ dtime = math.ceil(dtime)
4699
+
4700
+ else:
4701
+ dtime = int(dtime)
4702
 
4703
  if legacy_timings:
4704
  abs_time = int(e[1] / timings_divider) + timings_shift
 
4708
 
4709
  e[1] = max(0, abs_time + timings_shift)
4710
 
4711
+ if round_timings:
4712
+ e[2] = max(1, round(e[2] / timings_divider)) + timings_shift
4713
+
4714
+ else:
4715
+ if ceil_timings:
4716
+ e[2] = max(1, math.ceil(e[2] / timings_divider)) + timings_shift
4717
+ else:
4718
+ e[2] = max(1, int(e[2] / timings_divider)) + timings_shift
4719
 
4720
  e[4] = max(1, min(127, e[4] + pitch_shift))
4721
 
 
5165
  channels_index=3,
5166
  pitches_index=4,
5167
  patches_index=6,
5168
+ use_filtered_chords=False,
5169
+ use_full_chords=False,
5170
  remove_duplicate_pitches=True,
5171
+ fix_bad_tones_chords=False,
5172
+ fix_bad_pitches=False,
5173
  skip_drums=False
5174
  ):
5175
  fixed_chordified_score = []
 
5182
  else:
5183
  CHORDS = ALL_CHORDS_SORTED
5184
 
5185
+ if use_full_chords:
5186
+ CHORDS = ALL_CHORDS_FULL
5187
+
5188
  for c in chordified_score:
5189
 
5190
+ chord = copy.deepcopy(c)
5191
+
5192
  if remove_duplicate_pitches:
5193
 
5194
+ chord.sort(key = lambda x: x[pitches_index], reverse=True)
5195
 
5196
  seen = set()
5197
  ddchord = []
5198
 
5199
+ for cc in chord:
5200
  if cc[channels_index] != 9:
5201
 
5202
  if tuple([cc[pitches_index], cc[patches_index]]) not in seen:
 
5208
  else:
5209
  ddchord.append(cc)
5210
 
5211
+ chord = copy.deepcopy(ddchord)
5212
 
5213
+ tones_chord = sorted(set([t[pitches_index] % 12 for t in chord if t[channels_index] != 9]))
5214
 
5215
  if tones_chord:
5216
 
 
5222
  tones_counts = Counter([p % 12 for p in pitches_chord]).most_common()
5223
 
5224
  if tones_counts[0][1] > 1:
5225
+ good_tone = tones_counts[0][0]
5226
+ bad_tone = tones_counts[1][0]
5227
+
5228
  elif tones_counts[1][1] > 1:
5229
+ good_tone = tones_counts[1][0]
5230
+ bad_tone = tones_counts[0][0]
5231
+
5232
  else:
5233
+ good_tone = pitches_chord[0] % 12
5234
+ bad_tone = [t for t in tones_chord if t != good_tone][0]
5235
 
5236
+ tones_chord = [good_tone]
5237
+
5238
+ if fix_bad_tones_chords:
5239
+
5240
+ if good_tone > bad_tone:
5241
+
5242
+ if sorted([good_tone, (12+(bad_tone+1)) % 12]) in CHORDS:
5243
+ tones_chord = sorted([good_tone, (12+(bad_tone-1)) % 12])
5244
+
5245
+ elif sorted([good_tone, (12+(bad_tone-1)) % 12]) in CHORDS:
5246
+ tones_chord = sorted([good_tone, (12+(bad_tone+1)) % 12])
5247
+
5248
+ else:
5249
+
5250
+ if sorted([good_tone, (12+(bad_tone-1)) % 12]) in CHORDS:
5251
+ tones_chord = sorted([good_tone, (12+(bad_tone-1)) % 12])
5252
+
5253
+ elif sorted([good_tone, (12+(bad_tone+1)) % 12]) in CHORDS:
5254
+ tones_chord = sorted([good_tone, (12+(bad_tone+1)) % 12])
5255
+
5256
+ if len(tones_chord) > 2:
5257
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord)-1, 0, -1) for comb in combinations(tones_chord, i)]
5258
 
5259
  for co in tones_chord_combs:
5260
  if co in CHORDS:
 
5261
  break
5262
 
5263
+ if fix_bad_tones_chords:
5264
+
5265
+ dt_chord = list(set(co) ^ set(tones_chord))
5266
+
5267
+ for t in dt_chord:
5268
+ tones_chord.append((12+(t+1)) % 12)
5269
+ tones_chord.append((12+(t-1)) % 12)
5270
+
5271
+ ex_tones_chord = sorted(set(tones_chord))
5272
+
5273
+ tones_chord_combs = [list(comb) for i in range(4, 0, -2) for comb in combinations(ex_tones_chord, i) if all(t in list(comb) for t in co)]
5274
+
5275
+ for eco in tones_chord_combs:
5276
+ if eco in CHORDS:
5277
+ tones_chord = eco
5278
+ break
5279
+
5280
+ else:
5281
+ tones_chord = co
5282
+
5283
+ if len(tones_chord) == 1:
5284
+ tones_chord = [pitches_chord[0] % 12]
5285
+
5286
  bad_chords_counter += 1
5287
 
5288
+ chord.sort(key = lambda x: x[pitches_index], reverse=True)
5289
 
5290
+ new_chord = set()
5291
+ pipa = []
5292
 
5293
+ for e in chord:
5294
  if e[channels_index] != 9:
5295
  if e[pitches_index] % 12 in tones_chord:
5296
+ new_chord.add(tuple(e))
5297
+ pipa.append([e[pitches_index], e[patches_index]])
5298
 
5299
+ elif (e[pitches_index]+1) % 12 in tones_chord:
5300
+ e[pitches_index] += 1
5301
+ new_chord.add(tuple(e))
5302
+ pipa.append([e[pitches_index], e[patches_index]])
5303
+
5304
+ elif (e[pitches_index]-1) % 12 in tones_chord:
5305
+ e[pitches_index] -= 1
5306
+ new_chord.add(tuple(e))
5307
+ pipa.append([e[pitches_index], e[patches_index]])
5308
+
5309
+ if fix_bad_pitches:
5310
+
5311
+ bad_chord = set()
5312
+
5313
+ for e in chord:
5314
+ if e[channels_index] != 9:
5315
+
5316
+ if e[pitches_index] % 12 not in tones_chord:
5317
+ bad_chord.add(tuple(e))
5318
+
5319
+ elif (e[pitches_index]+1) % 12 not in tones_chord:
5320
+ bad_chord.add(tuple(e))
5321
+
5322
+ elif (e[pitches_index]-1) % 12 not in tones_chord:
5323
+ bad_chord.add(tuple(e))
5324
+
5325
+ for bc in bad_chord:
5326
+
5327
+ bc = list(bc)
5328
+
5329
+ tone = find_closest_tone(tones_chord, bc[pitches_index] % 12)
5330
+
5331
+ new_pitch = ((bc[pitches_index] // 12) * 12) + tone
5332
+
5333
+ if [new_pitch, bc[patches_index]] not in pipa:
5334
+ bc[pitches_index] = new_pitch
5335
+ new_chord.add(tuple(bc))
5336
+ pipa.append([[new_pitch], bc[patches_index]])
5337
+
5338
+ if not skip_drums:
5339
+ for e in c:
5340
+ if e[channels_index] == 9:
5341
+ new_chord.add(tuple(e))
5342
+
5343
+ new_chord = [list(e) for e in new_chord]
5344
+
5345
+ new_chord.sort(key = lambda x: (-x[pitches_index], x[patches_index]))
5346
 
5347
  fixed_chordified_score.append(new_chord)
5348
 
 
5538
  cur_chord.append(m)
5539
  cc = sorted(set(cur_chord))
5540
 
5541
+ if cc in ALL_CHORDS_FULL:
5542
  song.append(cc)
5543
 
5544
  else:
5545
+ while sorted(set(cur_chord)) not in ALL_CHORDS_FULL:
5546
  cur_chord.pop(0)
5547
  cc = sorted(set(cur_chord))
5548
  song.append(cc)
 
5679
  final_score_tokens_ints_seq = flatten(score_tokens_ints_seq)
5680
 
5681
  if max_seq_len > -1:
5682
+ final_score_tokens_ints_seq = final_score_tokens_ints_seq[:max_seq_len]
5683
 
5684
  if seq_pad_value > -1:
5685
  final_score_tokens_ints_seq += [seq_pad_value] * (max_seq_len - len(final_score_tokens_ints_seq))
 
5742
  def enhanced_chord_to_chord_token(enhanced_chord,
5743
  channels_index=3,
5744
  pitches_index=4,
5745
+ use_filtered_chords=False,
5746
+ use_full_chords=True
5747
  ):
5748
 
5749
  bad_chords_counter = 0
 
5754
  else:
5755
  CHORDS = ALL_CHORDS_SORTED
5756
 
5757
+ if use_full_chords:
5758
+ CHORDS = ALL_CHORDS_FULL
5759
+
5760
  tones_chord = sorted(set([t[pitches_index] % 12 for t in enhanced_chord if t[channels_index] != 9]))
5761
 
5762
  original_tones_chord = copy.deepcopy(tones_chord)
 
7200
 
7201
  def tones_chord_type(tones_chord,
7202
  return_chord_type_index=True,
7203
+ use_filtered_chords=False,
7204
+ use_full_chords=True
7205
  ):
7206
 
7207
  WN = WHITE_NOTES
 
7214
  else:
7215
  CHORDS = ALL_CHORDS_SORTED
7216
 
7217
+ if use_full_chords:
7218
+ CHORDS = ALL_CHORDS_FULL
7219
+
7220
  tones_chord = sorted(tones_chord)
7221
 
7222
  ctype = 'UNKNOWN'
 
7307
  def find_matching_tones_chords(tones_chord,
7308
  matching_chord_length=-1,
7309
  match_chord_type=True,
7310
+ use_filtered_chords=True,
7311
+ use_full_chords=True
7312
  ):
7313
 
7314
  if use_filtered_chords:
 
7316
  else:
7317
  CHORDS = ALL_CHORDS_SORTED
7318
 
7319
+ if use_full_chords:
7320
+ CHORDS = ALL_CHORDS_FULL
7321
+
7322
  tones_chord = sorted(tones_chord)
7323
 
7324
  tclen = len(tones_chord)
 
7501
  ###################################################################################
7502
 
7503
  def check_and_fix_pitches_chord(pitches_chord,
7504
+ remove_duplicate_pitches=True,
7505
+ use_filtered_chords=False,
7506
+ use_full_chords=True,
7507
+ fix_bad_pitches=False,
7508
  ):
7509
 
7510
+ if remove_duplicate_pitches:
7511
+ pitches_chord = sorted(set(pitches_chord), reverse=True)
7512
+ else:
7513
+ pitches_chord = sorted(pitches_chord, reverse=True)
7514
 
7515
  if use_filtered_chords:
7516
  CHORDS = ALL_CHORDS_FILTERED
7517
  else:
7518
  CHORDS = ALL_CHORDS_SORTED
7519
 
7520
+ if use_full_chords:
7521
+ CHORDS = ALL_CHORDS_FULL
7522
 
7523
+ chord = copy.deepcopy(pitches_chord)
7524
+
7525
+ tones_chord = sorted(set([t % 12 for t in chord]))
7526
+
7527
+ if tones_chord:
7528
 
7529
+ if tones_chord not in CHORDS:
7530
+
7531
+ if len(tones_chord) == 2:
7532
+ tones_counts = Counter([p % 12 for p in pitches_chord]).most_common()
7533
 
7534
+ if tones_counts[0][1] > 1:
7535
+ tones_chord = [tones_counts[0][0]]
7536
+
7537
+ elif tones_counts[1][1] > 1:
7538
+ tones_chord = [tones_counts[1][0]]
7539
+
7540
+ else:
7541
+ tones_chord = [pitches_chord[0] % 12]
7542
 
7543
+ else:
7544
+ tones_chord_combs = [list(comb) for i in range(len(tones_chord)-1, 0, -1) for comb in combinations(tones_chord, i)]
7545
+
7546
+ for co in tones_chord_combs:
7547
+ if co in CHORDS:
7548
+ tones_chord = co
7549
+ break
7550
 
7551
+ if len(tones_chord) == 1:
7552
+ tones_chord = [pitches_chord[0] % 12]
7553
+
7554
+ chord.sort(reverse=True)
7555
 
7556
+ new_chord = set()
7557
+ pipa = []
7558
 
7559
+ for e in chord:
7560
+ if e % 12 in tones_chord:
7561
+ new_chord.add(tuple([e]))
7562
+ pipa.append(e)
7563
 
7564
+ elif (e+1) % 12 in tones_chord:
7565
+ e += 1
7566
+ new_chord.add(tuple([e]))
7567
+ pipa.append(e)
7568
 
7569
+ elif (e-1) % 12 in tones_chord:
7570
+ e -= 1
7571
+ new_chord.add(tuple([e]))
7572
+ pipa.append(e)
7573
 
7574
+ if fix_bad_pitches:
7575
+
7576
+ bad_chord = set()
7577
+
7578
+ for e in chord:
7579
+
7580
+ if e % 12 not in tones_chord:
7581
+ bad_chord.add(tuple([e]))
7582
+
7583
+ elif (e+1) % 12 not in tones_chord:
7584
+ bad_chord.add(tuple([e]))
7585
+
7586
+ elif (e-1) % 12 not in tones_chord:
7587
+ bad_chord.add(tuple([e]))
7588
+
7589
+ for bc in bad_chord:
7590
+
7591
+ bc = list(bc)
7592
+
7593
+ tone = find_closest_tone(tones_chord, bc[0] % 12)
7594
+
7595
+ new_pitch = ((bc[0] // 12) * 12) + tone
7596
+
7597
+ if new_pitch not in pipa:
7598
+ new_chord.add(tuple([new_pitch]))
7599
+ pipa.append(new_pitch)
7600
+
7601
+ new_pitches_chord = [e[0] for e in new_chord]
7602
 
7603
  return sorted(new_pitches_chord, reverse=True)
7604
 
 
7790
 
7791
  def morph_tones_chord(tones_chord,
7792
  trg_tone,
7793
+ use_filtered_chords=True,
7794
+ use_full_chords=True
7795
  ):
7796
 
7797
  src_tones_chord = sorted(sorted(set(tones_chord)) + [trg_tone])
 
7806
  else:
7807
  CHORDS = ALL_CHORDS_SORTED
7808
 
7809
+ if use_full_chords:
7810
+ CHORDS = ALL_CHORDS_FULL
7811
+
7812
  for c in combs:
7813
  if sorted(set(c)) in CHORDS:
7814
  matches.append(sorted(set(c)))
 
8197
  n_patches = num_patches
8198
 
8199
  if group_patches:
8200
+ patches_set = sorted(set([e[6] for e in escore_notes]))
8201
  trg_patch_list = []
8202
  seen = []
8203
  for p in patches_set:
 
8208
  trg_patch_list = sorted(trg_patch_list)
8209
 
8210
  else:
8211
+ trg_patch_list = sorted(set([e[6] for e in escore_notes]))
8212
 
8213
  if 128 in trg_patch_list and n_patches > 1:
8214
  trg_patch_list = trg_patch_list[:n_patches-1] + [128]
 
8559
 
8560
  return [[c[0], c[1], c[1] / clen] for c in counts]
8561
 
8562
+ ###################################################################################
8563
+
8564
+ def smooth_escore_notes(escore_notes):
8565
+
8566
+ values = [e[4] % 24 for e in escore_notes]
8567
+
8568
+ smoothed = [values[0]]
8569
+
8570
+ for i in range(1, len(values)):
8571
+ if abs(smoothed[-1] - values[i]) >= 12:
8572
+ if smoothed[-1] < values[i]:
8573
+ smoothed.append(values[i] - 12)
8574
+ else:
8575
+ smoothed.append(values[i] + 12)
8576
+ else:
8577
+ smoothed.append(values[i])
8578
+
8579
+ smoothed_score = copy.deepcopy(escore_notes)
8580
+
8581
+ for i, e in enumerate(smoothed_score):
8582
+ esn_octave = escore_notes[i][4] // 12
8583
+ e[4] = (esn_octave * 12) + smoothed[i]
8584
+
8585
+ return smoothed_score
8586
+
8587
+ ###################################################################################
8588
+
8589
+ def add_base_to_escore_notes(escore_notes,
8590
+ base_octave=2,
8591
+ base_channel=2,
8592
+ base_patch=35,
8593
+ base_max_velocity=120,
8594
+ return_base=False
8595
+ ):
8596
+
8597
+
8598
+ score = copy.deepcopy(escore_notes)
8599
+
8600
+ cscore = chordify_score([1000, score])
8601
+
8602
+ base_score = []
8603
+
8604
+ for c in cscore:
8605
+ chord = sorted([e for e in c if e[3] != 9], key=lambda x: x[4], reverse=True)
8606
+ base_score.append(chord[-1])
8607
+
8608
+ base_score = smooth_escore_notes(base_score)
8609
+
8610
+ for e in base_score:
8611
+ e[3] = base_channel
8612
+ e[4] = (base_octave * 12) + (e[4] % 12)
8613
+ e[5] = e[4]
8614
+ e[6] = base_patch
8615
+
8616
+ adjust_score_velocities(base_score, base_max_velocity)
8617
+
8618
+ if return_base:
8619
+ final_score = sorted(base_score, key=lambda x: (x[1], -x[4], x[6]))
8620
+
8621
+ else:
8622
+ final_score = sorted(escore_notes + base_score, key=lambda x: (x[1], -x[4], x[6]))
8623
+
8624
+ return final_score
8625
+
8626
+ ###################################################################################
8627
+
8628
+ def add_drums_to_escore_notes(escore_notes,
8629
+ heavy_drums_pitches=[36, 38, 47],
8630
+ heavy_drums_velocity=110,
8631
+ light_drums_pitches=[51, 54],
8632
+ light_drums_velocity=127,
8633
+ drums_max_velocity=127,
8634
+ drums_ratio_time_divider=4,
8635
+ return_drums=False
8636
+ ):
8637
+
8638
+ score = copy.deepcopy([e for e in escore_notes if e[3] != 9])
8639
+
8640
+ cscore = chordify_score([1000, score])
8641
+
8642
+ drums_score = []
8643
+
8644
+ for c in cscore:
8645
+ min_dur = max(1, min([e[2] for e in c]))
8646
+ if not (c[0][1] % drums_ratio_time_divider):
8647
+ drum_note = ['note', c[0][1], min_dur, 9, heavy_drums_pitches[c[0][4] % len(heavy_drums_pitches)], heavy_drums_velocity, 128]
8648
+ else:
8649
+ drum_note = ['note', c[0][1], min_dur, 9, light_drums_pitches[c[0][4] % len(light_drums_pitches)], light_drums_velocity, 128]
8650
+ drums_score.append(drum_note)
8651
+
8652
+ adjust_score_velocities(drums_score, drums_max_velocity)
8653
+
8654
+ if return_drums:
8655
+ final_score = sorted(drums_score, key=lambda x: (x[1], -x[4], x[6]))
8656
+
8657
+ else:
8658
+ final_score = sorted(score + drums_score, key=lambda x: (x[1], -x[4], x[6]))
8659
+
8660
+ return final_score
8661
+
8662
+ ###################################################################################
8663
+
8664
+ def find_pattern_start_indexes(values, pattern):
8665
+
8666
+ start_indexes = []
8667
+
8668
+ count = 0
8669
+
8670
+ for i in range(len(values)- len(pattern)):
8671
+ chunk = values[i:i+len(pattern)]
8672
+
8673
+ if chunk == pattern:
8674
+ start_indexes.append(i)
8675
+
8676
+ return start_indexes
8677
+
8678
+ ###################################################################################
8679
+
8680
+ def escore_notes_lrno_pattern(escore_notes, mode='chords'):
8681
+
8682
+ cscore = chordify_score([1000, escore_notes])
8683
+
8684
+ checked_cscore = advanced_check_and_fix_chords_in_chordified_score(cscore)
8685
+
8686
+ chords_toks = []
8687
+ chords_idxs = []
8688
+
8689
+ for i, c in enumerate(checked_cscore[0]):
8690
+
8691
+ pitches = sorted([p[4] for p in c if p[3] != 9], reverse=True)
8692
+ tchord = pitches_to_tones_chord(pitches)
8693
+
8694
+ if tchord:
8695
+
8696
+ if mode == 'chords':
8697
+ token = ALL_CHORDS_FULL.index(tchord)
8698
+
8699
+ elif mode == 'high pitches':
8700
+ token = pitches[0]
8701
+
8702
+ elif mode == 'high pitches tones':
8703
+ token = pitches[0] % 12
8704
+
8705
+ else:
8706
+ token = ALL_CHORDS_FULL.index(tchord)
8707
+
8708
+ chords_toks.append(token)
8709
+ chords_idxs.append(i)
8710
+
8711
+ lrno_pats = find_lrno_patterns(chords_toks)
8712
+
8713
+ if lrno_pats:
8714
+
8715
+ lrno_pattern = list(lrno_pats[0][2])
8716
+
8717
+ start_idx = chords_idxs[find_pattern_start_indexes(chords_toks, lrno_pattern)[0]]
8718
+ end_idx = chords_idxs[start_idx + len(lrno_pattern)]
8719
+
8720
+ return recalculate_score_timings(flatten(cscore[start_idx:end_idx]))
8721
+
8722
+ else:
8723
+ return None
8724
+
8725
+ ###################################################################################
8726
+
8727
+ def chordified_score_pitches(chordified_score,
8728
+ mode='dominant',
8729
+ return_tones=False,
8730
+ omit_drums=True,
8731
+ score_patch=-1,
8732
+ channels_index=3,
8733
+ pitches_index=4,
8734
+ patches_index=6
8735
+ ):
8736
+
8737
+ results = []
8738
+
8739
+ for c in chordified_score:
8740
+
8741
+ if -1 < score_patch < 128:
8742
+ ptcs = sorted([e[pitches_index] for e in c if e[channels_index] != 9 and e[patches_index] == score_patch], reverse=True)
8743
+
8744
+ else:
8745
+ ptcs = sorted([e[pitches_index] for e in c if e[channels_index] != 9], reverse=True)
8746
+
8747
+ if ptcs:
8748
+
8749
+ if mode == 'dominant':
8750
+
8751
+ mtone = statistics.mode([p % 12 for p in ptcs])
8752
+
8753
+ if return_tones:
8754
+ results.append(mtone)
8755
+
8756
+ else:
8757
+ results.append(sorted(set([p for p in ptcs if p % 12 == mtone]), reverse=True))
8758
+
8759
+ elif mode == 'high':
8760
+
8761
+ if return_tones:
8762
+ results.append(ptcs[0] % 12)
8763
+
8764
+ else:
8765
+ results.append([ptcs[0]])
8766
+
8767
+ elif mode == 'base':
8768
+
8769
+ if return_tones:
8770
+ results.append(ptcs[-1] % 12)
8771
+
8772
+ else:
8773
+ results.append([ptcs[-1]])
8774
+
8775
+ elif mode == 'average':
8776
+
8777
+ if return_tones:
8778
+ results.append(statistics.mean(ptcs) % 12)
8779
+
8780
+ else:
8781
+ results.append([statistics.mean(ptcs)])
8782
+
8783
+ else:
8784
+
8785
+ mtone = statistics.mode([p % 12 for p in ptcs])
8786
+
8787
+ if return_tones:
8788
+ results.append(mtone)
8789
+
8790
+ else:
8791
+ results.append(sorted(set([p for p in ptcs if p % 12 == mtone]), reverse=True))
8792
+
8793
+ else:
8794
+
8795
+ if not omit_drums:
8796
+
8797
+ if return_tones:
8798
+ results.append(-1)
8799
+
8800
+ else:
8801
+ results.append([-1])
8802
+
8803
+ return results
8804
+
8805
+ ###################################################################################
8806
+
8807
+ def escore_notes_times_tones(escore_notes,
8808
+ tones_mode='dominant',
8809
+ return_abs_times=True,
8810
+ omit_drums=False
8811
+ ):
8812
+
8813
+ cscore = chordify_score([1000, escore_notes])
8814
+
8815
+ tones = chordified_score_pitches(cscore, return_tones=True, mode=tones_mode, omit_drums=omit_drums)
8816
+
8817
+ if return_abs_times:
8818
+ times = sorted([c[0][1] for c in cscore])
8819
+
8820
+ else:
8821
+ times = escore_notes_delta_times(escore_notes, omit_zeros=True, omit_drums=omit_drums)
8822
+
8823
+ if len(times) != len(tones):
8824
+ times = [0] + times
8825
+
8826
+ return [[t, to] for t, to in zip(times, tones)]
8827
+
8828
+ ###################################################################################
8829
+
8830
+ def escore_notes_middle(escore_notes,
8831
+ length=10,
8832
+ use_chords=True
8833
+ ):
8834
+
8835
+ if use_chords:
8836
+ score = chordify_score([1000, escore_notes])
8837
+
8838
+ else:
8839
+ score = escore_notes
8840
+
8841
+ middle_idx = len(score) // 2
8842
+
8843
+ slen = min(len(score) // 2, length // 2)
8844
+
8845
+ start_idx = middle_idx - slen
8846
+ end_idx = middle_idx + slen
8847
+
8848
+ if use_chords:
8849
+ return flatten(score[start_idx:end_idx])
8850
+
8851
+ else:
8852
+ return score[start_idx:end_idx]
8853
+
8854
+ ###################################################################################
8855
+
8856
+ ALL_CHORDS_FULL = [[0], [0, 3], [0, 3, 5], [0, 3, 5, 8], [0, 3, 5, 9], [0, 3, 5, 10], [0, 3, 6],
8857
+ [0, 3, 6, 9], [0, 3, 6, 10], [0, 3, 7], [0, 3, 7, 10], [0, 3, 8], [0, 3, 9],
8858
+ [0, 3, 10], [0, 4], [0, 4, 6], [0, 4, 6, 9], [0, 4, 6, 10], [0, 4, 7],
8859
+ [0, 4, 7, 10], [0, 4, 8], [0, 4, 9], [0, 4, 10], [0, 5], [0, 5, 8], [0, 5, 9],
8860
+ [0, 5, 10], [0, 6], [0, 6, 9], [0, 6, 10], [0, 7], [0, 7, 10], [0, 8], [0, 9],
8861
+ [0, 10], [1], [1, 4], [1, 4, 6], [1, 4, 6, 9], [1, 4, 6, 10], [1, 4, 6, 11],
8862
+ [1, 4, 7], [1, 4, 7, 10], [1, 4, 7, 11], [1, 4, 8], [1, 4, 8, 11], [1, 4, 9],
8863
+ [1, 4, 10], [1, 4, 11], [1, 5], [1, 5, 8], [1, 5, 8, 11], [1, 5, 9],
8864
+ [1, 5, 10], [1, 5, 11], [1, 6], [1, 6, 9], [1, 6, 10], [1, 6, 11], [1, 7],
8865
+ [1, 7, 10], [1, 7, 11], [1, 8], [1, 8, 11], [1, 9], [1, 10], [1, 11], [2],
8866
+ [2, 5], [2, 5, 8], [2, 5, 8, 11], [2, 5, 9], [2, 5, 10], [2, 5, 11], [2, 6],
8867
+ [2, 6, 9], [2, 6, 10], [2, 6, 11], [2, 7], [2, 7, 10], [2, 7, 11], [2, 8],
8868
+ [2, 8, 11], [2, 9], [2, 10], [2, 11], [3], [3, 5], [3, 5, 8], [3, 5, 8, 11],
8869
+ [3, 5, 9], [3, 5, 10], [3, 5, 11], [3, 6], [3, 6, 9], [3, 6, 10], [3, 6, 11],
8870
+ [3, 7], [3, 7, 10], [3, 7, 11], [3, 8], [3, 8, 11], [3, 9], [3, 10], [3, 11],
8871
+ [4], [4, 6], [4, 6, 9], [4, 6, 10], [4, 6, 11], [4, 7], [4, 7, 10], [4, 7, 11],
8872
+ [4, 8], [4, 8, 11], [4, 9], [4, 10], [4, 11], [5], [5, 8], [5, 8, 11], [5, 9],
8873
+ [5, 10], [5, 11], [6], [6, 9], [6, 10], [6, 11], [7], [7, 10], [7, 11], [8],
8874
+ [8, 11], [9], [10], [11]]
8875
+
8876
+ ###################################################################################
8877
+
8878
+ def escore_notes_to_parsons_code(escore_notes,
8879
+ times_index=1,
8880
+ pitches_index=4,
8881
+ return_as_list=False
8882
+ ):
8883
+
8884
+ parsons = "*"
8885
+ parsons_list = []
8886
+
8887
+ prev = ['note', -1, -1, -1, -1, -1, -1]
8888
+
8889
+ for e in escore_notes:
8890
+ if e[times_index] != prev[times_index]:
8891
+
8892
+ if e[pitches_index] > prev[pitches_index]:
8893
+ parsons += "U"
8894
+ parsons_list.append(1)
8895
+
8896
+ elif e[pitches_index] < prev[pitches_index]:
8897
+ parsons += "D"
8898
+ parsons_list.append(-1)
8899
+
8900
+ elif e[pitches_index] == prev[pitches_index]:
8901
+ parsons += "R"
8902
+ parsons_list.append(0)
8903
+
8904
+ prev = e
8905
+
8906
+ if return_as_list:
8907
+ return parsons_list
8908
+
8909
+ else:
8910
+ return parsons
8911
+
8912
+ ###################################################################################
8913
+
8914
+ def all_consequtive(list_of_values):
8915
+ return all(b > a for a, b in zip(list_of_values[:-1], list_of_values[1:]))
8916
+
8917
+ ###################################################################################
8918
+
8919
+ def escore_notes_patches(escore_notes, patches_index=6):
8920
+ return sorted(set([e[patches_index] for e in escore_notes]))
8921
+
8922
+ ###################################################################################
8923
+
8924
+ def build_suffix_array(lst):
8925
+
8926
+ n = len(lst)
8927
+
8928
+ suffixes = [(lst[i:], i) for i in range(n)]
8929
+ suffixes.sort()
8930
+ suffix_array = [suffix[1] for suffix in suffixes]
8931
+
8932
+ return suffix_array
8933
+
8934
+ ###################################################################################
8935
+
8936
+ def build_lcp_array(lst, suffix_array):
8937
+
8938
+ n = len(lst)
8939
+ rank = [0] * n
8940
+ lcp = [0] * n
8941
+
8942
+ for i, suffix in enumerate(suffix_array):
8943
+ rank[suffix] = i
8944
+
8945
+ h = 0
8946
+
8947
+ for i in range(n):
8948
+ if rank[i] > 0:
8949
+
8950
+ j = suffix_array[rank[i] - 1]
8951
+
8952
+ while i + h < n and j + h < n and lst[i + h] == lst[j + h]:
8953
+ h += 1
8954
+
8955
+ lcp[rank[i]] = h
8956
+
8957
+ if h > 0:
8958
+ h -= 1
8959
+
8960
+ return lcp
8961
+
8962
+ ###################################################################################
8963
+
8964
+ def find_lrno_pattern_fast(lst):
8965
+ n = len(lst)
8966
+ if n == 0:
8967
+ return []
8968
+
8969
+ suffix_array = build_suffix_array(lst)
8970
+ lcp_array = build_lcp_array(lst, suffix_array)
8971
+
8972
+ max_len = 0
8973
+ start_index = 0
8974
+
8975
+ for i in range(1, n):
8976
+ if lcp_array[i] > max_len:
8977
+ if suffix_array[i] + lcp_array[i] <= suffix_array[i - 1] or suffix_array[i - 1] + lcp_array[i - 1] <= suffix_array[i]:
8978
+ max_len = lcp_array[i]
8979
+ start_index = suffix_array[i]
8980
+
8981
+ return lst[start_index:start_index + max_len]
8982
+
8983
+ ###################################################################################
8984
+
8985
+ def find_chunk_indexes(original_list, chunk, ignore_index=-1):
8986
+
8987
+ chunk_length = len(chunk)
8988
+
8989
+ for i in range(len(original_list) - chunk_length + 1):
8990
+
8991
+ chunk_index = 0
8992
+ start_index = ignore_index
8993
+
8994
+ for j in range(i, len(original_list)):
8995
+ if original_list[j] == chunk[chunk_index]:
8996
+
8997
+ if start_index == ignore_index:
8998
+ start_index = j
8999
+
9000
+ chunk_index += 1
9001
+
9002
+ if chunk_index == chunk_length:
9003
+ return [start_index, j]
9004
+
9005
+ elif original_list[j] != ignore_index:
9006
+ break
9007
+
9008
+ return None
9009
+
9010
+ ###################################################################################
9011
+
9012
+ def escore_notes_lrno_pattern_fast(escore_notes,
9013
+ channels_index=3,
9014
+ pitches_index=4,
9015
+ zero_start_time=True
9016
+ ):
9017
+
9018
+ cscore = chordify_score([1000, escore_notes])
9019
+
9020
+ score_chords = []
9021
+
9022
+ for c in cscore:
9023
+
9024
+ tchord = sorted(set([e[pitches_index] % 12 for e in c if e[channels_index] != 9]))
9025
+
9026
+ chord_tok = -1
9027
+
9028
+ if tchord:
9029
+
9030
+ if tchord not in ALL_CHORDS_FULL:
9031
+ tchord = check_and_fix_tones_chord(tchord)
9032
+
9033
+ chord_tok = ALL_CHORDS_FULL.index(tchord)
9034
+
9035
+ score_chords.append(chord_tok)
9036
+
9037
+ schords = [c for c in score_chords if c != -1]
9038
+
9039
+ lrno = find_lrno_pattern_fast(schords)
9040
+
9041
+ if lrno:
9042
+
9043
+ sidx, eidx = find_chunk_indexes(score_chords, lrno)
9044
+
9045
+ escore_notes_lrno_pattern = flatten(cscore[sidx:eidx+1])
9046
+
9047
+ if escore_notes_lrno_pattern is not None:
9048
+
9049
+ if zero_start_time:
9050
+ return recalculate_score_timings(escore_notes_lrno_pattern)
9051
+
9052
+ else:
9053
+ return escore_notes_lrno_pattern
9054
+
9055
+ else:
9056
+ return None
9057
+
9058
+ else:
9059
+ return None
9060
+
9061
+ ###################################################################################
9062
+
9063
+ def escore_notes_durations_counter(escore_notes,
9064
+ min_duration=0,
9065
+ durations_index=2,
9066
+ channels_index=3
9067
+ ):
9068
+
9069
+ escore = [e for e in escore_notes if e[channels_index] != 9]
9070
+ durs = [e[durations_index] for e in escore if e[durations_index] >= min_duration]
9071
+ zero_durs = sum([1 for e in escore if e[durations_index] == 0])
9072
+
9073
+ return [len(durs), len(escore), zero_durs, Counter(durs).most_common()]
9074
+
9075
+ ###################################################################################
9076
+
9077
+ def count_bad_chords_in_chordified_score(chordified_score,
9078
+ pitches_index=4,
9079
+ patches_index=6,
9080
+ max_patch=127,
9081
+ use_full_chords=False
9082
+ ):
9083
+
9084
+ if use_full_chords:
9085
+ CHORDS = ALL_CHORDS_FULL
9086
+
9087
+ else:
9088
+ CHORDS = ALL_CHORDS_SORTED
9089
+
9090
+ bad_chords_count = 0
9091
+
9092
+ for c in chordified_score:
9093
+
9094
+ cpitches = [e[pitches_index] for e in c if e[patches_index] <= max_patch]
9095
+ tones_chord = sorted(set([p % 12 for p in cpitches]))
9096
+
9097
+ if tones_chord:
9098
+ if tones_chord not in CHORDS:
9099
+ bad_chords_count += 1
9100
+
9101
+ return [bad_chords_count, len(chordified_score)]
9102
+
9103
  ###################################################################################
9104
  #
9105
  # This is the end of the TMIDI X Python module
TPLOTS.py CHANGED
@@ -80,24 +80,25 @@ from PIL import Image
80
  # Constants
81
  ################################################################################
82
 
83
- ALL_CHORDS_FILTERED = [[0], [0, 3], [0, 3, 5], [0, 3, 5, 8], [0, 3, 5, 9], [0, 3, 5, 10], [0, 3, 7],
84
- [0, 3, 7, 10], [0, 3, 8], [0, 3, 9], [0, 3, 10], [0, 4], [0, 4, 6],
85
- [0, 4, 6, 9], [0, 4, 6, 10], [0, 4, 7], [0, 4, 7, 10], [0, 4, 8], [0, 4, 9],
86
- [0, 4, 10], [0, 5], [0, 5, 8], [0, 5, 9], [0, 5, 10], [0, 6], [0, 6, 9],
87
- [0, 6, 10], [0, 7], [0, 7, 10], [0, 8], [0, 9], [0, 10], [1], [1, 4],
88
- [1, 4, 6], [1, 4, 6, 9], [1, 4, 6, 10], [1, 4, 6, 11], [1, 4, 7],
89
- [1, 4, 7, 10], [1, 4, 7, 11], [1, 4, 8], [1, 4, 8, 11], [1, 4, 9], [1, 4, 10],
90
- [1, 4, 11], [1, 5], [1, 5, 8], [1, 5, 8, 11], [1, 5, 9], [1, 5, 10],
91
- [1, 5, 11], [1, 6], [1, 6, 9], [1, 6, 10], [1, 6, 11], [1, 7], [1, 7, 10],
92
- [1, 7, 11], [1, 8], [1, 8, 11], [1, 9], [1, 10], [1, 11], [2], [2, 5],
93
- [2, 5, 8], [2, 5, 8, 11], [2, 5, 9], [2, 5, 10], [2, 5, 11], [2, 6], [2, 6, 9],
94
- [2, 6, 10], [2, 6, 11], [2, 7], [2, 7, 10], [2, 7, 11], [2, 8], [2, 8, 11],
95
- [2, 9], [2, 10], [2, 11], [3], [3, 5], [3, 5, 8], [3, 5, 8, 11], [3, 5, 9],
96
- [3, 5, 10], [3, 5, 11], [3, 7], [3, 7, 10], [3, 7, 11], [3, 8], [3, 8, 11],
97
- [3, 9], [3, 10], [3, 11], [4], [4, 6], [4, 6, 9], [4, 6, 10], [4, 6, 11],
98
- [4, 7], [4, 7, 10], [4, 7, 11], [4, 8], [4, 8, 11], [4, 9], [4, 10], [4, 11],
99
- [5], [5, 8], [5, 8, 11], [5, 9], [5, 10], [5, 11], [6], [6, 9], [6, 10],
100
- [6, 11], [7], [7, 10], [7, 11], [8], [8, 11], [9], [10], [11]]
 
101
 
102
  ################################################################################
103
 
@@ -128,7 +129,7 @@ def tones_chord_type(tones_chord,
128
  MX = WHITE_NOTES + BLACK_NOTES
129
 
130
 
131
- CHORDS = ALL_CHORDS_FILTERED
132
 
133
  tones_chord = sorted(tones_chord)
134
 
@@ -1130,6 +1131,129 @@ def downsample_square_matrix(square_matrix, downsampling_factor=4):
1130
 
1131
  return dmatrix.tolist()
1132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1133
  ################################################################################
1134
  # [WIP] Future dev functions
1135
  ################################################################################
 
80
  # Constants
81
  ################################################################################
82
 
83
+ ALL_CHORDS_FULL = [[0], [0, 3], [0, 3, 5], [0, 3, 5, 8], [0, 3, 5, 9], [0, 3, 5, 10], [0, 3, 6],
84
+ [0, 3, 6, 9], [0, 3, 6, 10], [0, 3, 7], [0, 3, 7, 10], [0, 3, 8], [0, 3, 9],
85
+ [0, 3, 10], [0, 4], [0, 4, 6], [0, 4, 6, 9], [0, 4, 6, 10], [0, 4, 7],
86
+ [0, 4, 7, 10], [0, 4, 8], [0, 4, 9], [0, 4, 10], [0, 5], [0, 5, 8], [0, 5, 9],
87
+ [0, 5, 10], [0, 6], [0, 6, 9], [0, 6, 10], [0, 7], [0, 7, 10], [0, 8], [0, 9],
88
+ [0, 10], [1], [1, 4], [1, 4, 6], [1, 4, 6, 9], [1, 4, 6, 10], [1, 4, 6, 11],
89
+ [1, 4, 7], [1, 4, 7, 10], [1, 4, 7, 11], [1, 4, 8], [1, 4, 8, 11], [1, 4, 9],
90
+ [1, 4, 10], [1, 4, 11], [1, 5], [1, 5, 8], [1, 5, 8, 11], [1, 5, 9],
91
+ [1, 5, 10], [1, 5, 11], [1, 6], [1, 6, 9], [1, 6, 10], [1, 6, 11], [1, 7],
92
+ [1, 7, 10], [1, 7, 11], [1, 8], [1, 8, 11], [1, 9], [1, 10], [1, 11], [2],
93
+ [2, 5], [2, 5, 8], [2, 5, 8, 11], [2, 5, 9], [2, 5, 10], [2, 5, 11], [2, 6],
94
+ [2, 6, 9], [2, 6, 10], [2, 6, 11], [2, 7], [2, 7, 10], [2, 7, 11], [2, 8],
95
+ [2, 8, 11], [2, 9], [2, 10], [2, 11], [3], [3, 5], [3, 5, 8], [3, 5, 8, 11],
96
+ [3, 5, 9], [3, 5, 10], [3, 5, 11], [3, 6], [3, 6, 9], [3, 6, 10], [3, 6, 11],
97
+ [3, 7], [3, 7, 10], [3, 7, 11], [3, 8], [3, 8, 11], [3, 9], [3, 10], [3, 11],
98
+ [4], [4, 6], [4, 6, 9], [4, 6, 10], [4, 6, 11], [4, 7], [4, 7, 10], [4, 7, 11],
99
+ [4, 8], [4, 8, 11], [4, 9], [4, 10], [4, 11], [5], [5, 8], [5, 8, 11], [5, 9],
100
+ [5, 10], [5, 11], [6], [6, 9], [6, 10], [6, 11], [7], [7, 10], [7, 11], [8],
101
+ [8, 11], [9], [10], [11]]
102
 
103
  ################################################################################
104
 
 
129
  MX = WHITE_NOTES + BLACK_NOTES
130
 
131
 
132
+ CHORDS = ALL_CHORDS_FULL
133
 
134
  tones_chord = sorted(tones_chord)
135
 
 
1131
 
1132
  return dmatrix.tolist()
1133
 
1134
+ ################################################################################
1135
+
1136
+ def plot_parsons_code(parsons_code,
1137
+ start_pitch=60,
1138
+ return_plot_dict=False,
1139
+ return_plot_string=False,
1140
+ plot_size=(10, 10),
1141
+ labels_size=16,
1142
+ save_plot=''
1143
+ ):
1144
+
1145
+ '''
1146
+ Plot parsons code string
1147
+ '''
1148
+
1149
+ if parsons_code[0] != "*":
1150
+ return None
1151
+
1152
+ contour_dict = {}
1153
+ pitch = 0
1154
+ index = 0
1155
+
1156
+ maxp = 0
1157
+ minp = 0
1158
+
1159
+ contour_dict[(pitch, index)] = "*"
1160
+
1161
+ for point in parsons_code:
1162
+ if point == "R":
1163
+ index += 1
1164
+ contour_dict[(pitch, index)] = "-"
1165
+
1166
+ index += 1
1167
+ contour_dict[(pitch, index)] = "*"
1168
+
1169
+ elif point == "U":
1170
+ index += 1
1171
+ pitch -= 1
1172
+ contour_dict[(pitch, index)] = "/"
1173
+
1174
+ index += 1
1175
+ pitch -= 1
1176
+ contour_dict[(pitch, index)] = "*"
1177
+
1178
+ if pitch < maxp:
1179
+ maxp = pitch
1180
+
1181
+ elif point == "D":
1182
+ index += 1
1183
+ pitch += 1
1184
+ contour_dict[(pitch, index)] = "\\"
1185
+
1186
+ index += 1
1187
+ pitch += 1
1188
+ contour_dict[(pitch, index)] = "*"
1189
+
1190
+ if pitch > minp:
1191
+ minp = pitch
1192
+
1193
+ if return_plot_dict:
1194
+ return contour_dict
1195
+
1196
+ if return_plot_string:
1197
+
1198
+ plot_string = ''
1199
+
1200
+ for pitch in range(maxp, minp+1):
1201
+ line = [" " for _ in range(index + 1)]
1202
+ for pos in range(index + 1):
1203
+ if (pitch, pos) in contour_dict:
1204
+ line[pos] = contour_dict[(pitch, pos)]
1205
+
1206
+ plot_string = "".join(line)
1207
+
1208
+ return plot_string
1209
+
1210
+ labels = []
1211
+ pitches = []
1212
+ positions = []
1213
+ cur_pitch = start_pitch
1214
+ pitch_idx = 0
1215
+
1216
+ for k, v in contour_dict.items():
1217
+
1218
+ if v != '*':
1219
+
1220
+ pitches.append(cur_pitch)
1221
+ positions.append(pitch_idx)
1222
+
1223
+ if v == '/':
1224
+ cur_pitch += 1
1225
+ labels.append('U')
1226
+
1227
+ elif v == '\\':
1228
+ cur_pitch -= 1
1229
+ labels.append('D')
1230
+
1231
+ elif v == '-':
1232
+ labels.append('R')
1233
+
1234
+ pitch_idx += 1
1235
+
1236
+ plt.figure(figsize=plot_size)
1237
+
1238
+
1239
+ plt.plot(pitches)
1240
+
1241
+ for i, point in enumerate(zip(positions, pitches)):
1242
+ plt.annotate(labels[i], point, fontsize=labels_size)
1243
+
1244
+
1245
+ plt.title('Parsons Code with Labels', fontsize=labels_size)
1246
+ plt.xlabel('Position', fontsize=labels_size)
1247
+ plt.ylabel('Pitch', fontsize=labels_size)
1248
+
1249
+ if save_plot != '':
1250
+ plt.savefig(save_plot, bbox_inches="tight")
1251
+ plt.close()
1252
+
1253
+ plt.show()
1254
+
1255
+ plt.close()
1256
+
1257
  ################################################################################
1258
  # [WIP] Future dev functions
1259
  ################################################################################