asigalov61 commited on
Commit
09b1834
verified
1 Parent(s): c73324b

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +230 -43
TMIDIX.py CHANGED
@@ -51,7 +51,7 @@ r'''############################################################################
51
 
52
  ###################################################################################
53
 
54
- __version__ = "25.7.5"
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, max_velocity):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3728
 
3729
- min_velocity = min([c[5] for c in score])
3730
- max_velocity_all_channels = max([c[5] for c in score])
3731
- min_velocity_ratio = min_velocity / max_velocity_all_channels
 
 
 
 
 
 
 
 
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
- factor = max_velocity / max_channel_velocity
3738
- for i in range(len(score)):
3739
- score[i][5] = int(score[i][5] * factor)
 
 
 
 
 
 
 
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(enhanced_score_notes,
5033
- default_patch=0,
5034
- drums_patch=9,
5035
- verbose=False
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
- if e[0] == 'note':
5048
- if e[3] != 9:
5049
- if patches[e[3]] == -1:
5050
- patches[e[3]] = e[6]
5051
- else:
5052
- if patches[e[3]] != e[6]:
5053
- if e[6] in patches:
5054
- e[3] = patches.index(e[6])
5055
- else:
5056
- if -1 in patches:
5057
- patches[patches.index(-1)] = e[6]
5058
- else:
5059
- overflow_idx = idx
5060
- break
 
 
 
 
 
 
 
5061
 
5062
- enhanced_score_notes_with_patch_changes.append(e)
5063
 
5064
  #===========================================================================
5065
 
5066
  overflow_patches = []
 
 
 
 
 
5067
 
5068
  if overflow_idx != -1:
5069
- for idx, e in enumerate(enhanced_score_notes[overflow_idx:]):
5070
- if e[0] == 'note':
5071
- if e[3] != 9:
5072
- if e[6] not in patches:
5073
- if e[6] not in overflow_patches:
5074
- overflow_patches.append(e[6])
5075
- enhanced_score_notes_with_patch_changes.append(['patch_change', e[1], e[3], e[6]])
5076
- else:
5077
- e[3] = patches.index(e[6])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5078
 
5079
- enhanced_score_notes_with_patch_changes.append(e)
 
 
 
 
 
 
 
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('Composition patches')
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! :)')