Upload TMIDIX.py
Browse files
TMIDIX.py
CHANGED
|
@@ -8423,6 +8423,270 @@ 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
|
|
|
|
| 8423 |
|
| 8424 |
return [[c[0], c[1], c[1] / clen] for c in counts]
|
| 8425 |
|
| 8426 |
+
###################################################################################
|
| 8427 |
+
|
| 8428 |
+
def smooth_escore_notes(escore_notes):
|
| 8429 |
+
|
| 8430 |
+
values = [e[4] % 24 for e in escore_notes]
|
| 8431 |
+
|
| 8432 |
+
smoothed = [values[0]]
|
| 8433 |
+
|
| 8434 |
+
for i in range(1, len(values)):
|
| 8435 |
+
if abs(smoothed[-1] - values[i]) >= 12:
|
| 8436 |
+
if smoothed[-1] < values[i]:
|
| 8437 |
+
smoothed.append(values[i] - 12)
|
| 8438 |
+
else:
|
| 8439 |
+
smoothed.append(values[i] + 12)
|
| 8440 |
+
else:
|
| 8441 |
+
smoothed.append(values[i])
|
| 8442 |
+
|
| 8443 |
+
smoothed_score = copy.deepcopy(escore_notes)
|
| 8444 |
+
|
| 8445 |
+
for i, e in enumerate(smoothed_score):
|
| 8446 |
+
esn_octave = escore_notes[i][4] // 12
|
| 8447 |
+
e[4] = (esn_octave * 12) + smoothed[i]
|
| 8448 |
+
|
| 8449 |
+
return smoothed_score
|
| 8450 |
+
|
| 8451 |
+
###################################################################################
|
| 8452 |
+
|
| 8453 |
+
def add_base_to_escore_notes(escore_notes,
|
| 8454 |
+
base_octave=2,
|
| 8455 |
+
base_channel=2,
|
| 8456 |
+
base_patch=35,
|
| 8457 |
+
base_max_velocity=120,
|
| 8458 |
+
return_base=False
|
| 8459 |
+
):
|
| 8460 |
+
|
| 8461 |
+
|
| 8462 |
+
score = copy.deepcopy(escore_notes)
|
| 8463 |
+
|
| 8464 |
+
cscore = chordify_score([1000, score])
|
| 8465 |
+
|
| 8466 |
+
base_score = []
|
| 8467 |
+
|
| 8468 |
+
for c in cscore:
|
| 8469 |
+
chord = sorted([e for e in c if e[3] != 9], key=lambda x: x[4], reverse=True)
|
| 8470 |
+
base_score.append(chord[-1])
|
| 8471 |
+
|
| 8472 |
+
base_score = smooth_escore_notes(base_score)
|
| 8473 |
+
|
| 8474 |
+
for e in base_score:
|
| 8475 |
+
e[3] = base_channel
|
| 8476 |
+
e[4] = (base_octave * 12) + (e[4] % 12)
|
| 8477 |
+
e[5] = e[4]
|
| 8478 |
+
e[6] = base_patch
|
| 8479 |
+
|
| 8480 |
+
adjust_score_velocities(base_score, base_max_velocity)
|
| 8481 |
+
|
| 8482 |
+
if return_base:
|
| 8483 |
+
final_score = sorted(base_score, key=lambda x: (x[1], -x[4], x[6]))
|
| 8484 |
+
|
| 8485 |
+
else:
|
| 8486 |
+
final_score = sorted(escore_notes + base_score, key=lambda x: (x[1], -x[4], x[6]))
|
| 8487 |
+
|
| 8488 |
+
return final_score
|
| 8489 |
+
|
| 8490 |
+
###################################################################################
|
| 8491 |
+
|
| 8492 |
+
def add_drums_to_escore_notes(escore_notes,
|
| 8493 |
+
heavy_drums_pitches=[36, 38, 47],
|
| 8494 |
+
heavy_drums_velocity=110,
|
| 8495 |
+
light_drums_pitches=[51, 54],
|
| 8496 |
+
light_drums_velocity=127,
|
| 8497 |
+
drums_max_velocity=127,
|
| 8498 |
+
drums_ratio_time_divider=4,
|
| 8499 |
+
return_drums=False
|
| 8500 |
+
):
|
| 8501 |
+
|
| 8502 |
+
score = copy.deepcopy([e for e in escore_notes if e[3] != 9])
|
| 8503 |
+
|
| 8504 |
+
cscore = chordify_score([1000, score])
|
| 8505 |
+
|
| 8506 |
+
drums_score = []
|
| 8507 |
+
|
| 8508 |
+
for c in cscore:
|
| 8509 |
+
min_dur = max(1, min([e[2] for e in c]))
|
| 8510 |
+
if not (c[0][1] % drums_ratio_time_divider):
|
| 8511 |
+
drum_note = ['note', c[0][1], min_dur, 9, heavy_drums_pitches[c[0][4] % len(heavy_drums_pitches)], heavy_drums_velocity, 128]
|
| 8512 |
+
else:
|
| 8513 |
+
drum_note = ['note', c[0][1], min_dur, 9, light_drums_pitches[c[0][4] % len(light_drums_pitches)], light_drums_velocity, 128]
|
| 8514 |
+
drums_score.append(drum_note)
|
| 8515 |
+
|
| 8516 |
+
adjust_score_velocities(drums_score, drums_max_velocity)
|
| 8517 |
+
|
| 8518 |
+
if return_drums:
|
| 8519 |
+
final_score = sorted(drums_score, key=lambda x: (x[1], -x[4], x[6]))
|
| 8520 |
+
|
| 8521 |
+
else:
|
| 8522 |
+
final_score = sorted(score + drums_score, key=lambda x: (x[1], -x[4], x[6]))
|
| 8523 |
+
|
| 8524 |
+
return final_score
|
| 8525 |
+
|
| 8526 |
+
###################################################################################
|
| 8527 |
+
|
| 8528 |
+
def find_pattern_start_indexes(values, pattern):
|
| 8529 |
+
|
| 8530 |
+
start_indexes = []
|
| 8531 |
+
|
| 8532 |
+
count = 0
|
| 8533 |
+
|
| 8534 |
+
for i in range(len(values)- len(pattern)):
|
| 8535 |
+
chunk = values[i:i+len(pattern)]
|
| 8536 |
+
|
| 8537 |
+
if chunk == pattern:
|
| 8538 |
+
start_indexes.append(i)
|
| 8539 |
+
|
| 8540 |
+
return start_indexes
|
| 8541 |
+
|
| 8542 |
+
###################################################################################
|
| 8543 |
+
|
| 8544 |
+
def escore_notes_lrno_pattern(escore_notes, mode='chords'):
|
| 8545 |
+
|
| 8546 |
+
cscore = chordify_score([1000, escore_notes])
|
| 8547 |
+
|
| 8548 |
+
checked_cscore = advanced_check_and_fix_chords_in_chordified_score(cscore)
|
| 8549 |
+
|
| 8550 |
+
chords_toks = []
|
| 8551 |
+
chords_idxs = []
|
| 8552 |
+
|
| 8553 |
+
for i, c in enumerate(checked_cscore[0]):
|
| 8554 |
+
|
| 8555 |
+
pitches = sorted([p[4] for p in c if p[3] != 9], reverse=True)
|
| 8556 |
+
tchord = pitches_to_tones_chord(pitches)
|
| 8557 |
+
|
| 8558 |
+
if tchord:
|
| 8559 |
+
|
| 8560 |
+
if mode == 'chords':
|
| 8561 |
+
token = ALL_CHORDS_FILTERED.index(tchord)
|
| 8562 |
+
|
| 8563 |
+
elif mode == 'high pitches':
|
| 8564 |
+
token = pitches[0]
|
| 8565 |
+
|
| 8566 |
+
elif mode == 'high pitches tones':
|
| 8567 |
+
token = pitches[0] % 12
|
| 8568 |
+
|
| 8569 |
+
else:
|
| 8570 |
+
token = ALL_CHORDS_FILTERED.index(tchord)
|
| 8571 |
+
|
| 8572 |
+
chords_toks.append(token)
|
| 8573 |
+
chords_idxs.append(i)
|
| 8574 |
+
|
| 8575 |
+
lrno_pattern = list(find_lrno_patterns(chords_toks)[0][2])
|
| 8576 |
+
|
| 8577 |
+
if lrno_pattern:
|
| 8578 |
+
|
| 8579 |
+
start_idx = chords_idxs[find_pattern_start_indexes(chords_toks, lrno_pattern)[0]]
|
| 8580 |
+
end_idx = chords_idxs[start_idx + len(lrno_pattern)]
|
| 8581 |
+
|
| 8582 |
+
return recalculate_score_timings(flatten(checked_cscore[0][start_idx:end_idx]))
|
| 8583 |
+
|
| 8584 |
+
else:
|
| 8585 |
+
return None
|
| 8586 |
+
|
| 8587 |
+
###################################################################################
|
| 8588 |
+
|
| 8589 |
+
def chordified_score_pitches(chordified_score,
|
| 8590 |
+
mode='dominant',
|
| 8591 |
+
return_tones=False,
|
| 8592 |
+
omit_drums=True,
|
| 8593 |
+
score_patch=-1,
|
| 8594 |
+
channels_index=3,
|
| 8595 |
+
pitches_index=4,
|
| 8596 |
+
patches_index=6
|
| 8597 |
+
):
|
| 8598 |
+
|
| 8599 |
+
results = []
|
| 8600 |
+
|
| 8601 |
+
for c in chordified_score:
|
| 8602 |
+
|
| 8603 |
+
if -1 < score_patch < 128:
|
| 8604 |
+
ptcs = sorted([e[pitches_index] for e in c if e[channels_index] != 9 and e[patches_index] == score_patch], reverse=True)
|
| 8605 |
+
|
| 8606 |
+
else:
|
| 8607 |
+
ptcs = sorted([e[pitches_index] for e in c if e[channels_index] != 9], reverse=True)
|
| 8608 |
+
|
| 8609 |
+
if ptcs:
|
| 8610 |
+
|
| 8611 |
+
if mode == 'dominant':
|
| 8612 |
+
|
| 8613 |
+
mtone = statistics.mode([p % 12 for p in ptcs])
|
| 8614 |
+
|
| 8615 |
+
if return_tones:
|
| 8616 |
+
results.append(mtone)
|
| 8617 |
+
|
| 8618 |
+
else:
|
| 8619 |
+
results.append(sorted(set([p for p in ptcs if p % 12 == mtone]), reverse=True))
|
| 8620 |
+
|
| 8621 |
+
elif mode == 'high':
|
| 8622 |
+
|
| 8623 |
+
if return_tones:
|
| 8624 |
+
results.append(ptcs[0] % 12)
|
| 8625 |
+
|
| 8626 |
+
else:
|
| 8627 |
+
results.append([ptcs[0]])
|
| 8628 |
+
|
| 8629 |
+
elif mode == 'base':
|
| 8630 |
+
|
| 8631 |
+
if return_tones:
|
| 8632 |
+
results.append(ptcs[-1] % 12)
|
| 8633 |
+
|
| 8634 |
+
else:
|
| 8635 |
+
results.append([ptcs[-1]])
|
| 8636 |
+
|
| 8637 |
+
elif mode == 'average':
|
| 8638 |
+
|
| 8639 |
+
if return_tones:
|
| 8640 |
+
results.append(statistics.mean(ptcs) % 12)
|
| 8641 |
+
|
| 8642 |
+
else:
|
| 8643 |
+
results.append([statistics.mean(ptcs)])
|
| 8644 |
+
|
| 8645 |
+
else:
|
| 8646 |
+
|
| 8647 |
+
mtone = statistics.mode([p % 12 for p in ptcs])
|
| 8648 |
+
|
| 8649 |
+
if return_tones:
|
| 8650 |
+
results.append(mtone)
|
| 8651 |
+
|
| 8652 |
+
else:
|
| 8653 |
+
results.append(sorted(set([p for p in ptcs if p % 12 == mtone]), reverse=True))
|
| 8654 |
+
|
| 8655 |
+
else:
|
| 8656 |
+
|
| 8657 |
+
if not omit_drums:
|
| 8658 |
+
|
| 8659 |
+
if return_tones:
|
| 8660 |
+
results.append(-1)
|
| 8661 |
+
|
| 8662 |
+
else:
|
| 8663 |
+
results.append([-1])
|
| 8664 |
+
|
| 8665 |
+
return results
|
| 8666 |
+
|
| 8667 |
+
###################################################################################
|
| 8668 |
+
|
| 8669 |
+
def escore_notes_times_tones(escore_notes,
|
| 8670 |
+
tones_mode='dominant',
|
| 8671 |
+
return_abs_times=True,
|
| 8672 |
+
omit_drums=False
|
| 8673 |
+
):
|
| 8674 |
+
|
| 8675 |
+
cscore = chordify_score([1000, escore_notes])
|
| 8676 |
+
|
| 8677 |
+
tones = chordified_score_pitches(cscore, return_tones=True, mode=tones_mode, omit_drums=omit_drums)
|
| 8678 |
+
|
| 8679 |
+
if return_abs_times:
|
| 8680 |
+
times = sorted([c[0][1] for c in cscore])
|
| 8681 |
+
|
| 8682 |
+
else:
|
| 8683 |
+
times = escore_notes_delta_times(escore_notes, omit_zeros=True, omit_drums=omit_drums)
|
| 8684 |
+
|
| 8685 |
+
if len(times) != len(tones):
|
| 8686 |
+
times = [0] + times
|
| 8687 |
+
|
| 8688 |
+
return [[t, to] for t, to in zip(times, tones)]
|
| 8689 |
+
|
| 8690 |
###################################################################################
|
| 8691 |
#
|
| 8692 |
# This is the end of the TMIDI X Python module
|