Spaces:
Running
on
Zero
Running
on
Zero
Upload 2 files
Browse files
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:',
|
| 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 |
-
|
| 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 |
-
|
|
|
|
| 4624 |
|
| 4625 |
-
|
| 4626 |
-
|
| 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 |
-
|
| 4632 |
-
|
|
|
|
|
|
|
| 4633 |
|
| 4634 |
-
|
| 4635 |
|
| 4636 |
###################################################################################
|
| 4637 |
|
| 4638 |
def find_closest_tone(tones, tone):
|
| 4639 |
return min(tones, key=lambda x:abs(x-tone))
|
| 4640 |
|
| 4641 |
-
|
| 4642 |
|
| 4643 |
-
|
| 4644 |
|
| 4645 |
-
|
| 4646 |
-
ht = high_pitch % 12
|
| 4647 |
-
else:
|
| 4648 |
-
ht = 12
|
| 4649 |
|
| 4650 |
-
|
|
|
|
| 4651 |
|
| 4652 |
-
|
| 4653 |
-
|
| 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 |
-
|
| 4681 |
-
|
|
|
|
| 4682 |
|
| 4683 |
-
|
| 4684 |
-
|
| 4685 |
-
final_list.remove(0)
|
| 4686 |
-
else:
|
| 4687 |
-
final_list.remove(11)
|
| 4688 |
|
| 4689 |
-
|
| 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 |
-
|
|
|
|
|
|
|
| 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
|
| 4744 |
-
dtime =
|
| 4745 |
|
| 4746 |
else:
|
| 4747 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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=
|
|
|
|
| 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 |
-
|
| 5226 |
|
| 5227 |
seen = set()
|
| 5228 |
ddchord = []
|
| 5229 |
|
| 5230 |
-
for cc in
|
| 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 |
-
|
| 5243 |
|
| 5244 |
-
tones_chord = sorted(set([t[pitches_index] % 12 for t in
|
| 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 |
-
|
|
|
|
|
|
|
| 5257 |
elif tones_counts[1][1] > 1:
|
| 5258 |
-
|
|
|
|
|
|
|
| 5259 |
else:
|
| 5260 |
-
|
|
|
|
| 5261 |
|
| 5262 |
-
|
| 5263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 5273 |
|
| 5274 |
-
|
|
|
|
| 5275 |
|
| 5276 |
-
for e in
|
| 5277 |
if e[channels_index] != 9:
|
| 5278 |
if e[pitches_index] % 12 in tones_chord:
|
| 5279 |
-
new_chord.
|
|
|
|
| 5280 |
|
| 5281 |
-
|
| 5282 |
-
|
| 5283 |
-
new_chord.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 5480 |
song.append(cc)
|
| 5481 |
|
| 5482 |
else:
|
| 5483 |
-
while sorted(set(cur_chord)) not in
|
| 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 =
|
| 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=
|
|
|
|
| 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=
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
| 7431 |
):
|
| 7432 |
|
| 7433 |
-
|
|
|
|
|
|
|
|
|
|
| 7434 |
|
| 7435 |
if use_filtered_chords:
|
| 7436 |
CHORDS = ALL_CHORDS_FILTERED
|
| 7437 |
else:
|
| 7438 |
CHORDS = ALL_CHORDS_SORTED
|
| 7439 |
|
| 7440 |
-
|
|
|
|
| 7441 |
|
| 7442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7443 |
|
| 7444 |
-
|
|
|
|
|
|
|
|
|
|
| 7445 |
|
| 7446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7447 |
|
| 7448 |
-
|
| 7449 |
-
|
| 7450 |
-
|
| 7451 |
-
|
| 7452 |
-
|
| 7453 |
-
|
|
|
|
| 7454 |
|
| 7455 |
-
|
|
|
|
|
|
|
|
|
|
| 7456 |
|
| 7457 |
-
|
|
|
|
| 7458 |
|
| 7459 |
-
|
| 7460 |
-
|
| 7461 |
-
|
| 7462 |
-
|
| 7463 |
|
| 7464 |
-
|
|
|
|
|
|
|
|
|
|
| 7465 |
|
| 7466 |
-
|
|
|
|
|
|
|
|
|
|
| 7467 |
|
| 7468 |
-
|
| 7469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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
|
| 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 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
|
|
|
| 101 |
|
| 102 |
################################################################################
|
| 103 |
|
|
@@ -128,7 +129,7 @@ def tones_chord_type(tones_chord,
|
|
| 128 |
MX = WHITE_NOTES + BLACK_NOTES
|
| 129 |
|
| 130 |
|
| 131 |
-
CHORDS =
|
| 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 |
################################################################################
|