Spaces:
Running
on
Zero
Running
on
Zero
Upload TMIDIX.py
Browse files
TMIDIX.py
CHANGED
@@ -51,7 +51,7 @@ r'''############################################################################
|
|
51 |
|
52 |
###################################################################################
|
53 |
|
54 |
-
__version__ = "25.7.
|
55 |
|
56 |
print('=' * 70)
|
57 |
print('TMIDIX Python module')
|
@@ -3724,19 +3724,52 @@ def validate_pitches(chord, channel_to_check = 0, return_sorted = True):
|
|
3724 |
chord.sort(key = lambda x: x[4], reverse=True)
|
3725 |
return chord
|
3726 |
|
3727 |
-
def adjust_score_velocities(score,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3728 |
|
3729 |
-
|
3730 |
-
|
3731 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3732 |
|
3733 |
-
max_channel_velocity = max([c[5] for c in score])
|
3734 |
-
if max_channel_velocity < min_velocity:
|
3735 |
-
factor = max_velocity / min_velocity
|
3736 |
else:
|
3737 |
-
|
3738 |
-
|
3739 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3740 |
|
3741 |
def chordify_score(score,
|
3742 |
return_choridfied_score=True,
|
@@ -5029,54 +5062,101 @@ def patch_list_from_enhanced_score_notes(enhanced_score_notes,
|
|
5029 |
|
5030 |
###################################################################################
|
5031 |
|
5032 |
-
def patch_enhanced_score_notes(
|
5033 |
-
|
5034 |
-
|
5035 |
-
|
5036 |
-
|
|
|
|
|
5037 |
|
5038 |
-
#===========================================================================
|
|
|
|
|
|
|
|
|
5039 |
|
5040 |
enhanced_score_notes_with_patch_changes = []
|
5041 |
|
5042 |
patches = [-1] * 16
|
5043 |
|
|
|
|
|
|
|
5044 |
overflow_idx = -1
|
5045 |
|
5046 |
for idx, e in enumerate(enhanced_score_notes):
|
5047 |
-
|
5048 |
-
|
5049 |
-
|
5050 |
-
|
5051 |
-
|
5052 |
-
|
5053 |
-
|
5054 |
-
e[3] =
|
5055 |
-
|
5056 |
-
|
5057 |
-
|
5058 |
-
|
5059 |
-
|
5060 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5061 |
|
5062 |
-
|
5063 |
|
5064 |
#===========================================================================
|
5065 |
|
5066 |
overflow_patches = []
|
|
|
|
|
|
|
|
|
|
|
5067 |
|
5068 |
if overflow_idx != -1:
|
5069 |
-
|
5070 |
-
|
5071 |
-
|
5072 |
-
|
5073 |
-
|
5074 |
-
|
5075 |
-
|
5076 |
-
|
5077 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5078 |
|
5079 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5080 |
|
5081 |
#===========================================================================
|
5082 |
|
@@ -5086,9 +5166,13 @@ def patch_enhanced_score_notes(enhanced_score_notes,
|
|
5086 |
|
5087 |
#===========================================================================
|
5088 |
|
|
|
|
|
|
|
|
|
5089 |
if verbose:
|
5090 |
print('=' * 70)
|
5091 |
-
print('
|
5092 |
print('=' * 70)
|
5093 |
for c, p in enumerate(patches):
|
5094 |
print('Cha', str(c).zfill(2), '---', str(p).zfill(3), Number2patch[p])
|
@@ -5101,6 +5185,8 @@ def patch_enhanced_score_notes(enhanced_score_notes,
|
|
5101 |
print(str(p).zfill(3), Number2patch[p])
|
5102 |
print('=' * 70)
|
5103 |
|
|
|
|
|
5104 |
return enhanced_score_notes_with_patch_changes, patches, overflow_patches
|
5105 |
|
5106 |
###################################################################################
|
@@ -13417,6 +13503,107 @@ def find_deepest_midi_dirs(roots,
|
|
13417 |
|
13418 |
###################################################################################
|
13419 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13420 |
print('Module loaded!')
|
13421 |
print('=' * 70)
|
13422 |
print('Enjoy! :)')
|
|
|
51 |
|
52 |
###################################################################################
|
53 |
|
54 |
+
__version__ = "25.7.8"
|
55 |
|
56 |
print('=' * 70)
|
57 |
print('TMIDIX Python module')
|
|
|
3724 |
chord.sort(key = lambda x: x[4], reverse=True)
|
3725 |
return chord
|
3726 |
|
3727 |
+
def adjust_score_velocities(score,
|
3728 |
+
max_velocity,
|
3729 |
+
adj_per_channel=False,
|
3730 |
+
adj_in_place=True
|
3731 |
+
):
|
3732 |
+
|
3733 |
+
if adj_in_place:
|
3734 |
+
buf = score
|
3735 |
+
|
3736 |
+
else:
|
3737 |
+
buf = copy.deepcopy(score)
|
3738 |
+
|
3739 |
+
notes = [evt for evt in buf if evt[0] == 'note']
|
3740 |
+
|
3741 |
+
if not notes:
|
3742 |
+
return buf
|
3743 |
+
|
3744 |
+
if adj_per_channel:
|
3745 |
+
channel_max = {}
|
3746 |
+
|
3747 |
+
for _, _, _, ch, _, vel, _ in notes:
|
3748 |
+
channel_max[ch] = max(channel_max.get(ch, 0), vel)
|
3749 |
|
3750 |
+
channel_factor = {
|
3751 |
+
ch: (max_velocity / vmax if vmax > 0 else 1.0)
|
3752 |
+
for ch, vmax in channel_max.items()
|
3753 |
+
}
|
3754 |
+
|
3755 |
+
for evt in buf:
|
3756 |
+
if evt[0] == 'note':
|
3757 |
+
ch = evt[3]
|
3758 |
+
factor = channel_factor.get(ch, 1.0)
|
3759 |
+
new_vel = int(evt[5] * factor)
|
3760 |
+
evt[5] = max(1, min(127, new_vel))
|
3761 |
|
|
|
|
|
|
|
3762 |
else:
|
3763 |
+
global_max = max(vel for _, _, _, _, _, vel, _ in notes)
|
3764 |
+
factor = max_velocity / global_max if global_max > 0 else 1.0
|
3765 |
+
|
3766 |
+
for evt in buf:
|
3767 |
+
if evt[0] == 'note':
|
3768 |
+
new_vel = int(evt[5] * factor)
|
3769 |
+
evt[5] = max(1, min(127, new_vel))
|
3770 |
+
|
3771 |
+
if not adj_in_place:
|
3772 |
+
return buf
|
3773 |
|
3774 |
def chordify_score(score,
|
3775 |
return_choridfied_score=True,
|
|
|
5062 |
|
5063 |
###################################################################################
|
5064 |
|
5065 |
+
def patch_enhanced_score_notes(escore_notes,
|
5066 |
+
default_patch=0,
|
5067 |
+
reserved_patch=-1,
|
5068 |
+
reserved_patch_channel=-1,
|
5069 |
+
drums_patch=9,
|
5070 |
+
verbose=False
|
5071 |
+
):
|
5072 |
|
5073 |
+
#===========================================================================
|
5074 |
+
|
5075 |
+
enhanced_score_notes = copy.deepcopy(escore_notes)
|
5076 |
+
|
5077 |
+
#===========================================================================
|
5078 |
|
5079 |
enhanced_score_notes_with_patch_changes = []
|
5080 |
|
5081 |
patches = [-1] * 16
|
5082 |
|
5083 |
+
if -1 < reserved_patch < 128 and -1 < reserved_patch_channel < 128:
|
5084 |
+
patches[reserved_patch_channel] = reserved_patch
|
5085 |
+
|
5086 |
overflow_idx = -1
|
5087 |
|
5088 |
for idx, e in enumerate(enhanced_score_notes):
|
5089 |
+
if e[0] == 'note':
|
5090 |
+
if e[3] != 9:
|
5091 |
+
if -1 < reserved_patch < 128 and -1 < reserved_patch_channel < 128:
|
5092 |
+
if e[6] == reserved_patch:
|
5093 |
+
e[3] = reserved_patch_channel
|
5094 |
+
|
5095 |
+
if patches[e[3]] == -1:
|
5096 |
+
patches[e[3]] = e[6]
|
5097 |
+
|
5098 |
+
else:
|
5099 |
+
if patches[e[3]] != e[6]:
|
5100 |
+
if e[6] in patches:
|
5101 |
+
e[3] = patches.index(e[6])
|
5102 |
+
|
5103 |
+
else:
|
5104 |
+
if -1 in patches:
|
5105 |
+
patches[patches.index(-1)] = e[6]
|
5106 |
+
|
5107 |
+
else:
|
5108 |
+
overflow_idx = idx
|
5109 |
+
break
|
5110 |
|
5111 |
+
enhanced_score_notes_with_patch_changes.append(e)
|
5112 |
|
5113 |
#===========================================================================
|
5114 |
|
5115 |
overflow_patches = []
|
5116 |
+
overflow_channels = [-1] * 16
|
5117 |
+
overflow_channels[9] = drums_patch
|
5118 |
+
|
5119 |
+
if -1 < reserved_patch < 128 and -1 < reserved_patch_channel < 128:
|
5120 |
+
overflow_channels[reserved_patch_channel] = reserved_patch
|
5121 |
|
5122 |
if overflow_idx != -1:
|
5123 |
+
for idx, e in enumerate(enhanced_score_notes[overflow_idx:]):
|
5124 |
+
if e[0] == 'note':
|
5125 |
+
if e[3] != 9:
|
5126 |
+
if e[6] not in overflow_channels:
|
5127 |
+
|
5128 |
+
if -1 in overflow_channels:
|
5129 |
+
free_chan = overflow_channels.index(-1)
|
5130 |
+
overflow_channels[free_chan] = e[6]
|
5131 |
+
e[3] = free_chan
|
5132 |
+
|
5133 |
+
enhanced_score_notes_with_patch_changes.append(['patch_change', e[1], e[3], e[6]])
|
5134 |
+
|
5135 |
+
overflow_patches.append(e[6])
|
5136 |
+
|
5137 |
+
else:
|
5138 |
+
overflow_channels = [-1] * 16
|
5139 |
+
overflow_channels[9] = drums_patch
|
5140 |
+
|
5141 |
+
if -1 < reserved_patch < 128 and -1 < reserved_patch_channel < 128:
|
5142 |
+
overflow_channels[reserved_patch_channel] = reserved_patch
|
5143 |
+
e[3] = reserved_patch_channel
|
5144 |
+
|
5145 |
+
if e[6] != reserved_patch:
|
5146 |
+
|
5147 |
+
free_chan = overflow_channels.index(-1)
|
5148 |
+
e[3] = free_chan
|
5149 |
+
|
5150 |
+
overflow_channels[e[3]] = e[6]
|
5151 |
|
5152 |
+
enhanced_score_notes_with_patch_changes.append(['patch_change', e[1], e[3], e[6]])
|
5153 |
+
|
5154 |
+
overflow_patches.append(e[6])
|
5155 |
+
|
5156 |
+
else:
|
5157 |
+
e[3] = overflow_channels.index(e[6])
|
5158 |
+
|
5159 |
+
enhanced_score_notes_with_patch_changes.append(e)
|
5160 |
|
5161 |
#===========================================================================
|
5162 |
|
|
|
5166 |
|
5167 |
#===========================================================================
|
5168 |
|
5169 |
+
overflow_patches = ordered_set(overflow_patches)
|
5170 |
+
|
5171 |
+
#===========================================================================
|
5172 |
+
|
5173 |
if verbose:
|
5174 |
print('=' * 70)
|
5175 |
+
print('Main composition patches')
|
5176 |
print('=' * 70)
|
5177 |
for c, p in enumerate(patches):
|
5178 |
print('Cha', str(c).zfill(2), '---', str(p).zfill(3), Number2patch[p])
|
|
|
5185 |
print(str(p).zfill(3), Number2patch[p])
|
5186 |
print('=' * 70)
|
5187 |
|
5188 |
+
#===========================================================================
|
5189 |
+
|
5190 |
return enhanced_score_notes_with_patch_changes, patches, overflow_patches
|
5191 |
|
5192 |
###################################################################################
|
|
|
13503 |
|
13504 |
###################################################################################
|
13505 |
|
13506 |
+
PERCUSSION_GROUPS = {
|
13507 |
+
|
13508 |
+
1: { # Bass Drums
|
13509 |
+
35: 'Acoustic Bass Drum',
|
13510 |
+
36: 'Bass Drum 1',
|
13511 |
+
},
|
13512 |
+
2: { # Stick
|
13513 |
+
37: 'Side Stick',
|
13514 |
+
},
|
13515 |
+
3: { # Snares
|
13516 |
+
38: 'Acoustic Snare',
|
13517 |
+
40: 'Electric Snare',
|
13518 |
+
},
|
13519 |
+
4: { # Claps
|
13520 |
+
39: 'Hand Clap',
|
13521 |
+
},
|
13522 |
+
5: { # Floor Toms
|
13523 |
+
41: 'Low Floor Tom',
|
13524 |
+
43: 'High Floor Tom',
|
13525 |
+
},
|
13526 |
+
6: { # Hi-Hats
|
13527 |
+
42: 'Closed Hi-Hat',
|
13528 |
+
44: 'Pedal Hi-Hat',
|
13529 |
+
46: 'Open Hi-Hat',
|
13530 |
+
},
|
13531 |
+
7: { # Toms
|
13532 |
+
45: 'Low Tom',
|
13533 |
+
47: 'Low-Mid Tom',
|
13534 |
+
48: 'Hi-Mid Tom',
|
13535 |
+
50: 'High Tom',
|
13536 |
+
},
|
13537 |
+
8: { # Cymbals
|
13538 |
+
49: 'Crash Cymbal 1',
|
13539 |
+
51: 'Ride Cymbal 1',
|
13540 |
+
52: 'Chinese Cymbal',
|
13541 |
+
55: 'Splash Cymbal',
|
13542 |
+
57: 'Crash Cymbal 2',
|
13543 |
+
59: 'Ride Cymbal 2',
|
13544 |
+
},
|
13545 |
+
9: { # Bells
|
13546 |
+
53: 'Ride Bell',
|
13547 |
+
},
|
13548 |
+
10: { # Tambourine
|
13549 |
+
54: 'Tambourine',
|
13550 |
+
},
|
13551 |
+
11: { # Cowbell
|
13552 |
+
56: 'Cowbell',
|
13553 |
+
},
|
13554 |
+
12: { # Vibraslap
|
13555 |
+
58: 'Vibraslap',
|
13556 |
+
},
|
13557 |
+
13: { # Bongos
|
13558 |
+
60: 'Hi Bongo',
|
13559 |
+
61: 'Low Bongo',
|
13560 |
+
},
|
13561 |
+
14: { # Congas
|
13562 |
+
62: 'Mute Hi Conga',
|
13563 |
+
63: 'Open Hi Conga',
|
13564 |
+
64: 'Low Conga',
|
13565 |
+
},
|
13566 |
+
15: { # Timbales
|
13567 |
+
65: 'High Timbale',
|
13568 |
+
66: 'Low Timbale',
|
13569 |
+
},
|
13570 |
+
16: { # Agog么
|
13571 |
+
67: 'High Agogo',
|
13572 |
+
68: 'Low Agogo',
|
13573 |
+
},
|
13574 |
+
17: { # Cabasa
|
13575 |
+
69: 'Cabasa',
|
13576 |
+
},
|
13577 |
+
18: { # Maracas
|
13578 |
+
70: 'Maracas',
|
13579 |
+
},
|
13580 |
+
19: { # Whistles
|
13581 |
+
71: 'Short Whistle',
|
13582 |
+
72: 'Long Whistle',
|
13583 |
+
},
|
13584 |
+
20: { # Guiros
|
13585 |
+
73: 'Short Guiro',
|
13586 |
+
74: 'Long Guiro',
|
13587 |
+
},
|
13588 |
+
21: { # Claves
|
13589 |
+
75: 'Claves',
|
13590 |
+
},
|
13591 |
+
22: { # Wood Blocks
|
13592 |
+
76: 'Hi Wood Block',
|
13593 |
+
77: 'Low Wood Block',
|
13594 |
+
},
|
13595 |
+
23: { # Cuica
|
13596 |
+
78: 'Mute Cuica',
|
13597 |
+
79: 'Open Cuica',
|
13598 |
+
},
|
13599 |
+
24: { # Triangles
|
13600 |
+
80: 'Mute Triangle',
|
13601 |
+
81: 'Open Triangle',
|
13602 |
+
},
|
13603 |
+
}
|
13604 |
+
|
13605 |
+
###################################################################################
|
13606 |
+
|
13607 |
print('Module loaded!')
|
13608 |
print('=' * 70)
|
13609 |
print('Enjoy! :)')
|