Upload TMIDIX.py
Browse files
TMIDIX.py
CHANGED
|
@@ -1484,6 +1484,7 @@ from abc import ABC, abstractmethod
|
|
| 1484 |
from difflib import SequenceMatcher as SM
|
| 1485 |
|
| 1486 |
import statistics
|
|
|
|
| 1487 |
|
| 1488 |
import matplotlib.pyplot as plt
|
| 1489 |
|
|
@@ -6391,6 +6392,648 @@ def reverse_enhanced_score_notes(enhanced_score_notes):
|
|
| 6391 |
|
| 6392 |
###################################################################################
|
| 6393 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6394 |
# This is the end of the TMIDI X Python module
|
| 6395 |
|
| 6396 |
###################################################################################
|
|
|
|
| 1484 |
from difflib import SequenceMatcher as SM
|
| 1485 |
|
| 1486 |
import statistics
|
| 1487 |
+
import math
|
| 1488 |
|
| 1489 |
import matplotlib.pyplot as plt
|
| 1490 |
|
|
|
|
| 6392 |
|
| 6393 |
###################################################################################
|
| 6394 |
|
| 6395 |
+
def count_patterns(lst, sublist):
|
| 6396 |
+
count = 0
|
| 6397 |
+
idx = 0
|
| 6398 |
+
for i in range(len(lst) - len(sublist) + 1):
|
| 6399 |
+
if lst[idx:idx + len(sublist)] == sublist:
|
| 6400 |
+
count += 1
|
| 6401 |
+
idx += len(sublist)
|
| 6402 |
+
else:
|
| 6403 |
+
idx += 1
|
| 6404 |
+
return count
|
| 6405 |
+
|
| 6406 |
+
def find_lrno_patterns(seq):
|
| 6407 |
+
|
| 6408 |
+
all_seqs = Counter()
|
| 6409 |
+
|
| 6410 |
+
max_pat_len = math.ceil(len(seq) / 2)
|
| 6411 |
+
|
| 6412 |
+
num_iter = 0
|
| 6413 |
+
|
| 6414 |
+
for i in range(len(seq)):
|
| 6415 |
+
for j in range(i+1, len(seq)+1):
|
| 6416 |
+
if j-i <= max_pat_len:
|
| 6417 |
+
all_seqs[tuple(seq[i:j])] += 1
|
| 6418 |
+
num_iter += 1
|
| 6419 |
+
|
| 6420 |
+
max_count = 0
|
| 6421 |
+
max_len = 0
|
| 6422 |
+
|
| 6423 |
+
for val, count in all_seqs.items():
|
| 6424 |
+
|
| 6425 |
+
if max_len < len(val):
|
| 6426 |
+
max_count = max(2, count)
|
| 6427 |
+
|
| 6428 |
+
if count > 1:
|
| 6429 |
+
max_len = max(max_len, len(val))
|
| 6430 |
+
pval = val
|
| 6431 |
+
|
| 6432 |
+
max_pats = []
|
| 6433 |
+
|
| 6434 |
+
for val, count in all_seqs.items():
|
| 6435 |
+
if count == max_count and len(val) == max_len:
|
| 6436 |
+
max_pats.append(val)
|
| 6437 |
+
|
| 6438 |
+
found_patterns = []
|
| 6439 |
+
|
| 6440 |
+
for pat in max_pats:
|
| 6441 |
+
count = count_patterns(seq, list(pat))
|
| 6442 |
+
if count > 1:
|
| 6443 |
+
found_patterns.append([count, len(pat), pat])
|
| 6444 |
+
|
| 6445 |
+
return found_patterns
|
| 6446 |
+
|
| 6447 |
+
###################################################################################
|
| 6448 |
+
|
| 6449 |
+
def delta_pitches(escore_notes, pitches_index=4):
|
| 6450 |
+
|
| 6451 |
+
pitches = [p[pitches_index] for p in escore_notes]
|
| 6452 |
+
|
| 6453 |
+
return [a-b for a, b in zip(pitches[:-1], pitches[1:])]
|
| 6454 |
+
|
| 6455 |
+
###################################################################################
|
| 6456 |
+
|
| 6457 |
+
def split_list(lst, val):
|
| 6458 |
+
return [lst[i:j] for i, j in zip([0] + [k + 1 for k, x in enumerate(lst) if x == val], [k for k, x in enumerate(lst) if x == val] + [len(lst)]) if j > i]
|
| 6459 |
+
|
| 6460 |
+
###################################################################################
|
| 6461 |
+
|
| 6462 |
+
def even_timings(escore_notes,
|
| 6463 |
+
times_idx=1,
|
| 6464 |
+
durs_idx=2
|
| 6465 |
+
):
|
| 6466 |
+
|
| 6467 |
+
esn = copy.deepcopy(escore_notes)
|
| 6468 |
+
|
| 6469 |
+
for e in esn:
|
| 6470 |
+
|
| 6471 |
+
if e[times_idx] != 0:
|
| 6472 |
+
if e[times_idx] % 2 != 0:
|
| 6473 |
+
e[times_idx] += 1
|
| 6474 |
+
|
| 6475 |
+
if e[durs_idx] % 2 != 0:
|
| 6476 |
+
e[durs_idx] += 1
|
| 6477 |
+
|
| 6478 |
+
return esn
|
| 6479 |
+
|
| 6480 |
+
###################################################################################
|
| 6481 |
+
|
| 6482 |
+
def delta_score_to_abs_score(delta_score_notes,
|
| 6483 |
+
times_idx=1
|
| 6484 |
+
):
|
| 6485 |
+
|
| 6486 |
+
abs_score = copy.deepcopy(delta_score_notes)
|
| 6487 |
+
|
| 6488 |
+
abs_time = 0
|
| 6489 |
+
|
| 6490 |
+
for i, e in enumerate(delta_score_notes):
|
| 6491 |
+
|
| 6492 |
+
dtime = e[times_idx]
|
| 6493 |
+
|
| 6494 |
+
abs_time += dtime
|
| 6495 |
+
|
| 6496 |
+
abs_score[i][times_idx] = abs_time
|
| 6497 |
+
|
| 6498 |
+
return abs_score
|
| 6499 |
+
|
| 6500 |
+
###################################################################################
|
| 6501 |
+
|
| 6502 |
+
|
| 6503 |
+
def adjust_numbers_to_sum(numbers, target_sum):
|
| 6504 |
+
|
| 6505 |
+
current_sum = sum(numbers)
|
| 6506 |
+
difference = target_sum - current_sum
|
| 6507 |
+
|
| 6508 |
+
non_zero_elements = [(i, num) for i, num in enumerate(numbers) if num != 0]
|
| 6509 |
+
|
| 6510 |
+
total_non_zero = sum(num for _, num in non_zero_elements)
|
| 6511 |
+
|
| 6512 |
+
increments = []
|
| 6513 |
+
for i, num in non_zero_elements:
|
| 6514 |
+
proportion = num / total_non_zero
|
| 6515 |
+
increment = proportion * difference
|
| 6516 |
+
increments.append(increment)
|
| 6517 |
+
|
| 6518 |
+
for idx, (i, num) in enumerate(non_zero_elements):
|
| 6519 |
+
numbers[i] += int(round(increments[idx]))
|
| 6520 |
+
|
| 6521 |
+
current_sum = sum(numbers)
|
| 6522 |
+
difference = target_sum - current_sum
|
| 6523 |
+
non_zero_indices = [i for i, num in enumerate(numbers) if num != 0]
|
| 6524 |
+
|
| 6525 |
+
for i in range(abs(difference)):
|
| 6526 |
+
numbers[non_zero_indices[i % len(non_zero_indices)]] += 1 if difference > 0 else -1
|
| 6527 |
+
|
| 6528 |
+
return numbers
|
| 6529 |
+
|
| 6530 |
+
###################################################################################
|
| 6531 |
+
|
| 6532 |
+
def find_next_bar(escore_notes, bar_time, start_note_idx, cur_bar):
|
| 6533 |
+
for e in escore_notes[start_note_idx:]:
|
| 6534 |
+
if e[1] // bar_time > cur_bar:
|
| 6535 |
+
return e, escore_notes.index(e)
|
| 6536 |
+
|
| 6537 |
+
###################################################################################
|
| 6538 |
+
|
| 6539 |
+
def align_escore_notes_to_bars(escore_notes,
|
| 6540 |
+
bar_time=4000,
|
| 6541 |
+
trim_durations=False,
|
| 6542 |
+
split_durations=False
|
| 6543 |
+
):
|
| 6544 |
+
|
| 6545 |
+
#=============================================================================
|
| 6546 |
+
|
| 6547 |
+
aligned_escore_notes = copy.deepcopy(escore_notes)
|
| 6548 |
+
|
| 6549 |
+
abs_time = 0
|
| 6550 |
+
nidx = 0
|
| 6551 |
+
delta = 0
|
| 6552 |
+
bcount = 0
|
| 6553 |
+
next_bar = [0]
|
| 6554 |
+
|
| 6555 |
+
#=============================================================================
|
| 6556 |
+
|
| 6557 |
+
while next_bar:
|
| 6558 |
+
|
| 6559 |
+
next_bar = find_next_bar(escore_notes, bar_time, nidx, bcount)
|
| 6560 |
+
|
| 6561 |
+
if next_bar:
|
| 6562 |
+
|
| 6563 |
+
gescore_notes = escore_notes[nidx:next_bar[1]]
|
| 6564 |
+
else:
|
| 6565 |
+
gescore_notes = escore_notes[nidx:]
|
| 6566 |
+
|
| 6567 |
+
original_timings = [delta] + [(b[1]-a[1]) for a, b in zip(gescore_notes[:-1], gescore_notes[1:])]
|
| 6568 |
+
adj_timings = adjust_numbers_to_sum(original_timings, bar_time)
|
| 6569 |
+
|
| 6570 |
+
for t in adj_timings:
|
| 6571 |
+
|
| 6572 |
+
abs_time += t
|
| 6573 |
+
|
| 6574 |
+
aligned_escore_notes[nidx][1] = abs_time
|
| 6575 |
+
aligned_escore_notes[nidx][2] -= int(bar_time // 200)
|
| 6576 |
+
|
| 6577 |
+
nidx += 1
|
| 6578 |
+
|
| 6579 |
+
if next_bar:
|
| 6580 |
+
delta = escore_notes[next_bar[1]][1]-escore_notes[next_bar[1]-1][1]
|
| 6581 |
+
bcount += 1
|
| 6582 |
+
|
| 6583 |
+
#=============================================================================
|
| 6584 |
+
|
| 6585 |
+
aligned_adjusted_escore_notes = []
|
| 6586 |
+
bcount = 0
|
| 6587 |
+
|
| 6588 |
+
for a in aligned_escore_notes:
|
| 6589 |
+
bcount = a[1] // bar_time
|
| 6590 |
+
nbtime = bar_time * (bcount+1)
|
| 6591 |
+
|
| 6592 |
+
if a[1]+a[2] > nbtime and a[3] != 9:
|
| 6593 |
+
if trim_durations or split_durations:
|
| 6594 |
+
ddiff = ((a[1]+a[2])-nbtime)
|
| 6595 |
+
aa = copy.deepcopy(a)
|
| 6596 |
+
aa[2] = a[2] - ddiff
|
| 6597 |
+
aligned_adjusted_escore_notes.append(aa)
|
| 6598 |
+
|
| 6599 |
+
if split_durations:
|
| 6600 |
+
aaa = copy.deepcopy(a)
|
| 6601 |
+
aaa[1] = a[1]+aa[2]
|
| 6602 |
+
aaa[2] = ddiff
|
| 6603 |
+
|
| 6604 |
+
aligned_adjusted_escore_notes.append(aaa)
|
| 6605 |
+
|
| 6606 |
+
else:
|
| 6607 |
+
aligned_adjusted_escore_notes.append(a)
|
| 6608 |
+
|
| 6609 |
+
else:
|
| 6610 |
+
aligned_adjusted_escore_notes.append(a)
|
| 6611 |
+
|
| 6612 |
+
#=============================================================================
|
| 6613 |
+
|
| 6614 |
+
return aligned_adjusted_escore_notes
|
| 6615 |
+
|
| 6616 |
+
###################################################################################
|
| 6617 |
+
|
| 6618 |
+
def normalize_chord_durations(chord,
|
| 6619 |
+
dur_idx=2,
|
| 6620 |
+
norm_factor=100
|
| 6621 |
+
):
|
| 6622 |
+
|
| 6623 |
+
nchord = copy.deepcopy(chord)
|
| 6624 |
+
|
| 6625 |
+
for c in nchord:
|
| 6626 |
+
c[dur_idx] = int(round(max(1 / norm_factor, c[dur_idx] // norm_factor) * norm_factor))
|
| 6627 |
+
|
| 6628 |
+
return nchord
|
| 6629 |
+
|
| 6630 |
+
###################################################################################
|
| 6631 |
+
|
| 6632 |
+
def normalize_chordified_score_durations(chordified_score,
|
| 6633 |
+
dur_idx=2,
|
| 6634 |
+
norm_factor=100
|
| 6635 |
+
):
|
| 6636 |
+
|
| 6637 |
+
ncscore = copy.deepcopy(chordified_score)
|
| 6638 |
+
|
| 6639 |
+
for cc in ncscore:
|
| 6640 |
+
for c in cc:
|
| 6641 |
+
c[dur_idx] = int(round(max(1 / norm_factor, c[dur_idx] // norm_factor) * norm_factor))
|
| 6642 |
+
|
| 6643 |
+
return ncscore
|
| 6644 |
+
|
| 6645 |
+
###################################################################################
|
| 6646 |
+
|
| 6647 |
+
def horizontal_ordered_list_search(list_of_lists,
|
| 6648 |
+
query_list,
|
| 6649 |
+
start_idx=0,
|
| 6650 |
+
end_idx=-1
|
| 6651 |
+
):
|
| 6652 |
+
|
| 6653 |
+
lol = list_of_lists
|
| 6654 |
+
|
| 6655 |
+
results = []
|
| 6656 |
+
|
| 6657 |
+
if start_idx > 0:
|
| 6658 |
+
lol = list_of_lists[start_idx:]
|
| 6659 |
+
|
| 6660 |
+
if start_idx == -1:
|
| 6661 |
+
idx = -1
|
| 6662 |
+
for i, l in enumerate(list_of_lists):
|
| 6663 |
+
try:
|
| 6664 |
+
idx = l.index(query_list[0])
|
| 6665 |
+
lol = list_of_lists[i:]
|
| 6666 |
+
break
|
| 6667 |
+
except:
|
| 6668 |
+
continue
|
| 6669 |
+
|
| 6670 |
+
if idx == -1:
|
| 6671 |
+
results.append(-1)
|
| 6672 |
+
return results
|
| 6673 |
+
else:
|
| 6674 |
+
results.append(i)
|
| 6675 |
+
|
| 6676 |
+
if end_idx != -1:
|
| 6677 |
+
lol = list_of_lists[start_idx:start_idx+max(end_idx, len(query_list))]
|
| 6678 |
+
|
| 6679 |
+
for i, q in enumerate(query_list):
|
| 6680 |
+
try:
|
| 6681 |
+
idx = lol[i].index(q)
|
| 6682 |
+
results.append(idx)
|
| 6683 |
+
except:
|
| 6684 |
+
results.append(-1)
|
| 6685 |
+
return results
|
| 6686 |
+
|
| 6687 |
+
return results
|
| 6688 |
+
|
| 6689 |
+
###################################################################################
|
| 6690 |
+
|
| 6691 |
+
def escore_notes_to_escore_matrix(escore_notes,
|
| 6692 |
+
alt_velocities=False
|
| 6693 |
+
):
|
| 6694 |
+
|
| 6695 |
+
last_time = escore_notes[-1][1]
|
| 6696 |
+
last_notes = [e for e in escore_notes if e[1] == last_time]
|
| 6697 |
+
max_last_dur = max([e[2] for e in last_notes])
|
| 6698 |
+
|
| 6699 |
+
time_range = last_time+max_last_dur
|
| 6700 |
+
|
| 6701 |
+
channels_list = sorted(set([e[3] for e in escore_notes]))
|
| 6702 |
+
|
| 6703 |
+
escore_matrixes = []
|
| 6704 |
+
|
| 6705 |
+
for cha in channels_list:
|
| 6706 |
+
|
| 6707 |
+
escore_matrix = [[[-1, -1]] * 128 for _ in range(time_range)]
|
| 6708 |
+
|
| 6709 |
+
pe = escore_notes[0]
|
| 6710 |
+
|
| 6711 |
+
for i, note in enumerate(escore_notes):
|
| 6712 |
+
|
| 6713 |
+
etype, time, duration, channel, pitch, velocity, patch = note
|
| 6714 |
+
|
| 6715 |
+
time = max(0, time)
|
| 6716 |
+
duration = max(2, duration)
|
| 6717 |
+
channel = max(0, min(15, channel))
|
| 6718 |
+
pitch = max(0, min(127, pitch))
|
| 6719 |
+
velocity = max(0, min(127, velocity))
|
| 6720 |
+
patch = max(0, min(128, patch))
|
| 6721 |
+
|
| 6722 |
+
if alt_velocities:
|
| 6723 |
+
velocity -= (i % 2)
|
| 6724 |
+
|
| 6725 |
+
if channel == cha:
|
| 6726 |
+
|
| 6727 |
+
for t in range(time, min(time + duration, time_range)):
|
| 6728 |
+
|
| 6729 |
+
escore_matrix[t][pitch] = [velocity, patch]
|
| 6730 |
+
|
| 6731 |
+
pe = note
|
| 6732 |
+
|
| 6733 |
+
escore_matrixes.append(escore_matrix)
|
| 6734 |
+
|
| 6735 |
+
return [channels_list, escore_matrixes]
|
| 6736 |
+
|
| 6737 |
+
###################################################################################
|
| 6738 |
+
|
| 6739 |
+
def escore_matrix_to_merged_escore_notes(full_escore_matrix,
|
| 6740 |
+
max_note_duration=4000
|
| 6741 |
+
):
|
| 6742 |
+
|
| 6743 |
+
merged_escore_notes = []
|
| 6744 |
+
|
| 6745 |
+
mat_channels_list = full_escore_matrix[0]
|
| 6746 |
+
|
| 6747 |
+
for m, cha in enumerate(mat_channels_list):
|
| 6748 |
+
|
| 6749 |
+
escore_matrix = full_escore_matrix[1][m]
|
| 6750 |
+
|
| 6751 |
+
result = []
|
| 6752 |
+
|
| 6753 |
+
for j in range(len(escore_matrix[0])):
|
| 6754 |
+
|
| 6755 |
+
count = 1
|
| 6756 |
+
|
| 6757 |
+
for i in range(1, len(escore_matrix)):
|
| 6758 |
+
|
| 6759 |
+
if escore_matrix[i][j] != [-1, -1] and escore_matrix[i][j][1] == escore_matrix[i-1][j][1] and count < max_note_duration:
|
| 6760 |
+
count += 1
|
| 6761 |
+
|
| 6762 |
+
else:
|
| 6763 |
+
if count > 1:
|
| 6764 |
+
result.append([i-count, count, j, escore_matrix[i-1][j]])
|
| 6765 |
+
|
| 6766 |
+
count = 1
|
| 6767 |
+
|
| 6768 |
+
if count > 1:
|
| 6769 |
+
result.append([len(escore_matrix)-count, count, j, escore_matrix[-1][j]])
|
| 6770 |
+
|
| 6771 |
+
result.sort(key=lambda x: (x[0], -x[2]))
|
| 6772 |
+
|
| 6773 |
+
for r in result:
|
| 6774 |
+
merged_escore_notes.append(['note', r[0], r[1], cha, r[2], r[3][0], r[3][1]])
|
| 6775 |
+
|
| 6776 |
+
return sorted(merged_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
|
| 6777 |
+
|
| 6778 |
+
###################################################################################
|
| 6779 |
+
|
| 6780 |
+
def escore_matrix_to_original_escore_notes(full_escore_matrix):
|
| 6781 |
+
|
| 6782 |
+
merged_escore_notes = []
|
| 6783 |
+
|
| 6784 |
+
mat_channels_list = full_escore_matrix[0]
|
| 6785 |
+
|
| 6786 |
+
for m, cha in enumerate(mat_channels_list):
|
| 6787 |
+
|
| 6788 |
+
escore_matrix = full_escore_matrix[1][m]
|
| 6789 |
+
|
| 6790 |
+
result = []
|
| 6791 |
+
|
| 6792 |
+
for j in range(len(escore_matrix[0])):
|
| 6793 |
+
|
| 6794 |
+
count = 1
|
| 6795 |
+
|
| 6796 |
+
for i in range(1, len(escore_matrix)):
|
| 6797 |
+
|
| 6798 |
+
if escore_matrix[i][j] != [-1, -1] and escore_matrix[i][j] == escore_matrix[i-1][j]:
|
| 6799 |
+
count += 1
|
| 6800 |
+
|
| 6801 |
+
else:
|
| 6802 |
+
if count > 1:
|
| 6803 |
+
result.append([i-count, count, j, escore_matrix[i-1][j]])
|
| 6804 |
+
|
| 6805 |
+
count = 1
|
| 6806 |
+
|
| 6807 |
+
if count > 1:
|
| 6808 |
+
result.append([len(escore_matrix)-count, count, j, escore_matrix[-1][j]])
|
| 6809 |
+
|
| 6810 |
+
result.sort(key=lambda x: (x[0], -x[2]))
|
| 6811 |
+
|
| 6812 |
+
for r in result:
|
| 6813 |
+
merged_escore_notes.append(['note', r[0], r[1], cha, r[2], r[3][0], r[3][1]])
|
| 6814 |
+
|
| 6815 |
+
return sorted(merged_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
|
| 6816 |
+
|
| 6817 |
+
###################################################################################
|
| 6818 |
+
|
| 6819 |
+
def escore_notes_to_binary_matrix(escore_notes,
|
| 6820 |
+
channel=0,
|
| 6821 |
+
patch=0
|
| 6822 |
+
):
|
| 6823 |
+
|
| 6824 |
+
escore = [e for e in escore_notes if e[3] == channel and e[6] == patch]
|
| 6825 |
+
|
| 6826 |
+
if escore:
|
| 6827 |
+
last_time = escore[-1][1]
|
| 6828 |
+
last_notes = [e for e in escore if e[1] == last_time]
|
| 6829 |
+
max_last_dur = max([e[2] for e in last_notes])
|
| 6830 |
+
|
| 6831 |
+
time_range = last_time+max_last_dur
|
| 6832 |
+
|
| 6833 |
+
escore_matrix = []
|
| 6834 |
+
|
| 6835 |
+
escore_matrix = [[0] * 128 for _ in range(time_range)]
|
| 6836 |
+
|
| 6837 |
+
for note in escore:
|
| 6838 |
+
|
| 6839 |
+
etype, time, duration, chan, pitch, velocity, pat = note
|
| 6840 |
+
|
| 6841 |
+
time = max(0, time)
|
| 6842 |
+
duration = max(2, duration)
|
| 6843 |
+
chan = max(0, min(15, chan))
|
| 6844 |
+
pitch = max(0, min(127, pitch))
|
| 6845 |
+
velocity = max(0, min(127, velocity))
|
| 6846 |
+
pat = max(0, min(128, pat))
|
| 6847 |
+
|
| 6848 |
+
if channel == chan and patch == pat:
|
| 6849 |
+
|
| 6850 |
+
for t in range(time, min(time + duration, time_range)):
|
| 6851 |
+
|
| 6852 |
+
escore_matrix[t][pitch] = 1
|
| 6853 |
+
|
| 6854 |
+
return escore_matrix
|
| 6855 |
+
|
| 6856 |
+
else:
|
| 6857 |
+
return None
|
| 6858 |
+
|
| 6859 |
+
###################################################################################
|
| 6860 |
+
|
| 6861 |
+
def binary_matrix_to_original_escore_notes(binary_matrix,
|
| 6862 |
+
channel=0,
|
| 6863 |
+
patch=0,
|
| 6864 |
+
velocity=90
|
| 6865 |
+
):
|
| 6866 |
+
|
| 6867 |
+
result = []
|
| 6868 |
+
|
| 6869 |
+
for j in range(len(binary_matrix[0])):
|
| 6870 |
+
|
| 6871 |
+
count = 1
|
| 6872 |
+
|
| 6873 |
+
for i in range(1, len(binary_matrix)):
|
| 6874 |
+
|
| 6875 |
+
if binary_matrix[i][j] != 0 and binary_matrix[i][j] == binary_matrix[i-1][j]:
|
| 6876 |
+
count += 1
|
| 6877 |
+
|
| 6878 |
+
else:
|
| 6879 |
+
if count > 1:
|
| 6880 |
+
result.append([i-count, count, j, binary_matrix[i-1][j]])
|
| 6881 |
+
|
| 6882 |
+
count = 1
|
| 6883 |
+
|
| 6884 |
+
if count > 1:
|
| 6885 |
+
result.append([len(binary_matrix)-count, count, j, binary_matrix[-1][j]])
|
| 6886 |
+
|
| 6887 |
+
result.sort(key=lambda x: (x[0], -x[2]))
|
| 6888 |
+
|
| 6889 |
+
original_escore_notes = []
|
| 6890 |
+
|
| 6891 |
+
for r in result:
|
| 6892 |
+
original_escore_notes.append(['note', r[0], r[1], channel, r[2], velocity, patch])
|
| 6893 |
+
|
| 6894 |
+
return sorted(original_escore_notes, key=lambda x: (x[1], -x[4], x[6]))
|
| 6895 |
+
|
| 6896 |
+
###################################################################################
|
| 6897 |
+
|
| 6898 |
+
def escore_notes_averages(escore_notes,
|
| 6899 |
+
times_index=1,
|
| 6900 |
+
durs_index=2,
|
| 6901 |
+
chans_index=3,
|
| 6902 |
+
ptcs_index=4,
|
| 6903 |
+
vels_index=5,
|
| 6904 |
+
average_drums=False,
|
| 6905 |
+
score_is_delta=False,
|
| 6906 |
+
return_ptcs_and_vels=False
|
| 6907 |
+
):
|
| 6908 |
+
|
| 6909 |
+
if score_is_delta:
|
| 6910 |
+
if average_drums:
|
| 6911 |
+
times = [e[times_index] for e in escore_notes if e[times_index] != 0]
|
| 6912 |
+
else:
|
| 6913 |
+
times = [e[times_index] for e in escore_notes if e[times_index] != 0 and e[chans_index] != 9]
|
| 6914 |
+
|
| 6915 |
+
else:
|
| 6916 |
+
descore_notes = delta_score_notes(escore_notes)
|
| 6917 |
+
if average_drums:
|
| 6918 |
+
times = [e[times_index] for e in descore_notes if e[times_index] != 0]
|
| 6919 |
+
else:
|
| 6920 |
+
times = [e[times_index] for e in descore_notes if e[times_index] != 0 and e[chans_index] != 9]
|
| 6921 |
+
|
| 6922 |
+
if average_drums:
|
| 6923 |
+
durs = [e[durs_index] for e in escore_notes]
|
| 6924 |
+
else:
|
| 6925 |
+
durs = [e[durs_index] for e in escore_notes if e[chans_index] != 9]
|
| 6926 |
+
|
| 6927 |
+
if return_ptcs_and_vels:
|
| 6928 |
+
if average_drums:
|
| 6929 |
+
ptcs = [e[ptcs_index] for e in escore_notes]
|
| 6930 |
+
vels = [e[vels_index] for e in escore_notes]
|
| 6931 |
+
else:
|
| 6932 |
+
ptcs = [e[ptcs_index] for e in escore_notes if e[chans_index] != 9]
|
| 6933 |
+
vels = [e[vels_index] for e in escore_notes if e[chans_index] != 9]
|
| 6934 |
+
|
| 6935 |
+
return [sum(times) / len(times), sum(durs) / len(durs), sum(ptcs) / len(ptcs), sum(vels) / len(vels)]
|
| 6936 |
+
|
| 6937 |
+
else:
|
| 6938 |
+
return [sum(times) / len(times), sum(durs) / len(durs)]
|
| 6939 |
+
|
| 6940 |
+
###################################################################################
|
| 6941 |
+
|
| 6942 |
+
def adjust_escore_notes_timings(escore_notes,
|
| 6943 |
+
adj_k=1,
|
| 6944 |
+
times_index=1,
|
| 6945 |
+
durs_index=2,
|
| 6946 |
+
score_is_delta=False,
|
| 6947 |
+
return_delta_scpre=False
|
| 6948 |
+
):
|
| 6949 |
+
|
| 6950 |
+
if score_is_delta:
|
| 6951 |
+
adj_escore_notes = copy.deepcopy(escore_notes)
|
| 6952 |
+
else:
|
| 6953 |
+
adj_escore_notes = delta_score_notes(escore_notes)
|
| 6954 |
+
|
| 6955 |
+
for e in adj_escore_notes:
|
| 6956 |
+
|
| 6957 |
+
if e[times_index] != 0:
|
| 6958 |
+
e[times_index] = max(1, round(e[times_index] * adj_k))
|
| 6959 |
+
|
| 6960 |
+
e[durs_index] = max(1, round(e[durs_index] * adj_k))
|
| 6961 |
+
|
| 6962 |
+
if return_delta_scpre:
|
| 6963 |
+
return adj_escore_notes
|
| 6964 |
+
|
| 6965 |
+
else:
|
| 6966 |
+
return delta_score_to_abs_score(adj_escore_notes)
|
| 6967 |
+
|
| 6968 |
+
###################################################################################
|
| 6969 |
+
|
| 6970 |
+
def escore_notes_delta_times(escore_notes,
|
| 6971 |
+
times_index=1
|
| 6972 |
+
):
|
| 6973 |
+
|
| 6974 |
+
descore_notes = delta_score_notes(escore_notes)
|
| 6975 |
+
|
| 6976 |
+
return [e[times_index] for e in descore_notes]
|
| 6977 |
+
|
| 6978 |
+
###################################################################################
|
| 6979 |
+
|
| 6980 |
+
def escore_notes_durations(escore_notes,
|
| 6981 |
+
durs_index=1
|
| 6982 |
+
):
|
| 6983 |
+
|
| 6984 |
+
descore_notes = delta_score_notes(escore_notes)
|
| 6985 |
+
|
| 6986 |
+
return [e[durs_index] for e in descore_notes]
|
| 6987 |
+
|
| 6988 |
+
###################################################################################
|
| 6989 |
+
|
| 6990 |
+
def ordered_lists_match_ratio(src_list, trg_list):
|
| 6991 |
+
|
| 6992 |
+
zlist = list(zip(src_list, trg_list))
|
| 6993 |
+
|
| 6994 |
+
return sum([a == b for a, b in zlist]) / len(list(zlist))
|
| 6995 |
+
|
| 6996 |
+
###################################################################################
|
| 6997 |
+
|
| 6998 |
+
def lists_intersections(src_list, trg_list):
|
| 6999 |
+
return list(set(src_list) & set(trg_list))
|
| 7000 |
+
|
| 7001 |
+
###################################################################################
|
| 7002 |
+
|
| 7003 |
+
def transpose_escore_notes(escore_notes,
|
| 7004 |
+
transpose_value=0,
|
| 7005 |
+
channel_index=3,
|
| 7006 |
+
pitches_index=4
|
| 7007 |
+
):
|
| 7008 |
+
|
| 7009 |
+
tr_escore_notes = copy.deepcopy(escore_notes)
|
| 7010 |
+
|
| 7011 |
+
for e in tr_escore_notes:
|
| 7012 |
+
if e[channel_index] != 9:
|
| 7013 |
+
e[pitches_index] = max(1, min(127, e[pitches_index] + transpose_value))
|
| 7014 |
+
|
| 7015 |
+
return tr_escore_notes
|
| 7016 |
+
|
| 7017 |
+
###################################################################################
|
| 7018 |
+
|
| 7019 |
+
def transpose_escore_notes_to_pitch(escore_notes,
|
| 7020 |
+
target_pitch_value=60,
|
| 7021 |
+
channel_index=3,
|
| 7022 |
+
pitches_index=4
|
| 7023 |
+
):
|
| 7024 |
+
|
| 7025 |
+
tr_escore_notes = copy.deepcopy(escore_notes)
|
| 7026 |
+
|
| 7027 |
+
transpose_delta = int(round(target_pitch_value)) - int(round(escore_notes_averages(escore_notes, return_ptcs_and_vels=True)[2]))
|
| 7028 |
+
|
| 7029 |
+
for e in tr_escore_notes:
|
| 7030 |
+
if e[channel_index] != 9:
|
| 7031 |
+
e[pitches_index] = max(1, min(127, e[pitches_index] + transpose_delta))
|
| 7032 |
+
|
| 7033 |
+
return tr_escore_notes
|
| 7034 |
+
|
| 7035 |
+
###################################################################################
|
| 7036 |
+
|
| 7037 |
# This is the end of the TMIDI X Python module
|
| 7038 |
|
| 7039 |
###################################################################################
|