asigalov61 commited on
Commit
b86f1dd
1 Parent(s): 87798b9

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +172 -5
TMIDIX.py CHANGED
@@ -1656,13 +1656,15 @@ def Tegridy_SONG_to_MIDI_Converter(SONG,
1656
 
1657
  ###################################################################################
1658
 
1659
- def Tegridy_ms_SONG_to_MIDI_Converter(SONG,
1660
  output_signature = 'Tegridy TMIDI Module',
1661
  track_name = 'Composition Track',
1662
  list_of_MIDI_patches = [0, 24, 32, 40, 42, 46, 56, 71, 73, 0, 0, 0, 0, 0, 0, 0],
1663
  output_file_name = 'TMIDI-Composition',
1664
  text_encoding='ISO-8859-1',
1665
- verbose=True):
 
 
1666
 
1667
  '''Tegridy milisecond SONG to MIDI Converter
1668
 
@@ -1672,12 +1674,14 @@ def Tegridy_ms_SONG_to_MIDI_Converter(SONG,
1672
  List of 16 MIDI patch numbers for output MIDI. Def. is MuseNet compatible patches.
1673
  Output file name w/o .mid extension.
1674
  Optional text encoding if you are working with text_events/lyrics. This is especially useful for Karaoke. Please note that anything but ISO-8859-1 is a non-standard way of encoding text_events according to MIDI specs.
 
 
1675
 
1676
  Output: MIDI File
1677
  Detailed MIDI stats
1678
 
1679
  Project Los Angeles
1680
- Tegridy Code 2020'''
1681
 
1682
  if verbose:
1683
  print('Converting to MIDI. Please stand-by...')
@@ -1705,6 +1709,14 @@ def Tegridy_ms_SONG_to_MIDI_Converter(SONG,
1705
  ['patch_change', 0, 15, list_of_MIDI_patches[15]],
1706
  ['track_name', 0, bytes(track_name, text_encoding)]]
1707
 
 
 
 
 
 
 
 
 
1708
  output = output_header + [patch_list + SONG]
1709
 
1710
  midi_data = score2midi(output, text_encoding)
@@ -4710,8 +4722,8 @@ def extract_melody(chordified_enhanced_score,
4710
  if e[4] < melody_range[0]:
4711
  e[4] = (e[4] % 12) + melody_range[0]
4712
 
4713
- if e[4] > melody_range[1]:
4714
- e[4] = (e[4] % 12) + melody_range[1]
4715
 
4716
  return fix_monophonic_score_durations(melody_score)
4717
 
@@ -4793,6 +4805,161 @@ ALL_CHORDS_SORTED = [[0], [0, 2], [0, 3], [0, 4], [0, 2, 4], [0, 5], [0, 2, 5],
4793
 
4794
  ###################################################################################
4795
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4796
  # This is the end of the TMIDI X Python module
4797
 
4798
  ###################################################################################
 
1656
 
1657
  ###################################################################################
1658
 
1659
+ def Tegridy_ms_SONG_to_MIDI_Converter(ms_SONG,
1660
  output_signature = 'Tegridy TMIDI Module',
1661
  track_name = 'Composition Track',
1662
  list_of_MIDI_patches = [0, 24, 32, 40, 42, 46, 56, 71, 73, 0, 0, 0, 0, 0, 0, 0],
1663
  output_file_name = 'TMIDI-Composition',
1664
  text_encoding='ISO-8859-1',
1665
+ timings_multiplier=1,
1666
+ verbose=True
1667
+ ):
1668
 
1669
  '''Tegridy milisecond SONG to MIDI Converter
1670
 
 
1674
  List of 16 MIDI patch numbers for output MIDI. Def. is MuseNet compatible patches.
1675
  Output file name w/o .mid extension.
1676
  Optional text encoding if you are working with text_events/lyrics. This is especially useful for Karaoke. Please note that anything but ISO-8859-1 is a non-standard way of encoding text_events according to MIDI specs.
1677
+ Optional timings multiplier
1678
+ Optional verbose output
1679
 
1680
  Output: MIDI File
1681
  Detailed MIDI stats
1682
 
1683
  Project Los Angeles
1684
+ Tegridy Code 2024'''
1685
 
1686
  if verbose:
1687
  print('Converting to MIDI. Please stand-by...')
 
1709
  ['patch_change', 0, 15, list_of_MIDI_patches[15]],
1710
  ['track_name', 0, bytes(track_name, text_encoding)]]
1711
 
1712
+ SONG = copy.deepcopy(ms_SONG)
1713
+
1714
+ if timings_multiplier != 1:
1715
+ for S in SONG:
1716
+ S[1] = S[1] * timings_multiplier
1717
+ if S[0] == 'note':
1718
+ S[2] = S[2] * timings_multiplier
1719
+
1720
  output = output_header + [patch_list + SONG]
1721
 
1722
  midi_data = score2midi(output, text_encoding)
 
4722
  if e[4] < melody_range[0]:
4723
  e[4] = (e[4] % 12) + melody_range[0]
4724
 
4725
+ if e[4] >= melody_range[1]:
4726
+ e[4] = (e[4] % 12) + (melody_range[1]-12)
4727
 
4728
  return fix_monophonic_score_durations(melody_score)
4729
 
 
4805
 
4806
  ###################################################################################
4807
 
4808
+ MIDI_Instruments_Families = {
4809
+ 0: 'Piano Family',
4810
+ 1: 'Chromatic Percussion Family',
4811
+ 2: 'Organ Family',
4812
+ 3: 'Guitar Family',
4813
+ 4: 'Bass Family',
4814
+ 5: 'Strings Family',
4815
+ 6: 'Ensemble Family',
4816
+ 7: 'Brass Family',
4817
+ 8: 'Reed Family',
4818
+ 9: 'Pipe Family',
4819
+ 10: 'Synth Lead Family',
4820
+ 11: 'Synth Pad Family',
4821
+ 12: 'Synth Effects Family',
4822
+ 13: 'Ethnic Family',
4823
+ 14: 'Percussive Family',
4824
+ 15: 'Sound Effects Family',
4825
+ 16: 'Drums Family',
4826
+ -1: 'Unknown Family',
4827
+ }
4828
+
4829
+ ###################################################################################
4830
+
4831
+ def patch_to_instrument_family(MIDI_patch, drums_patch=128):
4832
+
4833
+ if 0 <= MIDI_patch < 128:
4834
+ return MIDI_patch // 8, MIDI_Instruments_Families[MIDI_patch // 8]
4835
+
4836
+ elif MIDI_patch == drums_patch:
4837
+ return MIDI_patch // 8, MIDI_Instruments_Families[16]
4838
+
4839
+ else:
4840
+ return -1, MIDI_Instruments_Families[-1]
4841
+
4842
+ ###################################################################################
4843
+
4844
+ def patch_list_from_enhanced_score_notes(enhanced_score_notes,
4845
+ default_patch=0,
4846
+ drums_patch=9,
4847
+ verbose=False
4848
+ ):
4849
+
4850
+ patches = [-1] * 16
4851
+
4852
+ for idx, e in enumerate(enhanced_score_notes):
4853
+ if e[3] != 9:
4854
+ if patches[e[3]] == -1:
4855
+ patches[e[3]] = e[6]
4856
+ else:
4857
+ if patches[e[3]] != e[6]:
4858
+ if e[6] in patches:
4859
+ e[3] = patches.index(e[6])
4860
+ else:
4861
+ if -1 in patches:
4862
+ patches[patches.index(-1)] = e[6]
4863
+ else:
4864
+ patches[-1] = e[6]
4865
+
4866
+ if verbose:
4867
+ print('=' * 70)
4868
+ print('WARNING! Composition has more than 15 patches!')
4869
+ print('Conflict note number:', idx)
4870
+ print('Conflict channel number:', e[3])
4871
+ print('Conflict patch number:', e[6])
4872
+
4873
+ patches = [p if p != -1 else default_patch for p in patches]
4874
+
4875
+ patches[9] = drums_patch
4876
+
4877
+ if verbose:
4878
+ print('=' * 70)
4879
+ print('Composition patches')
4880
+ print('=' * 70)
4881
+ for c, p in enumerate(patches):
4882
+ print('Cha', str(c).zfill(2), '---', str(p).zfill(3), Number2patch[p])
4883
+ print('=' * 70)
4884
+
4885
+ return patches
4886
+
4887
+ ###################################################################################
4888
+
4889
+ def patch_enhanced_score_notes(enhanced_score_notes,
4890
+ default_patch=0,
4891
+ drums_patch=9,
4892
+ verbose=False
4893
+ ):
4894
+
4895
+ #===========================================================================
4896
+
4897
+ enhanced_score_notes_with_patch_changes = []
4898
+
4899
+ patches = [-1] * 16
4900
+
4901
+ overflow_idx = -1
4902
+
4903
+ for idx, e in enumerate(enhanced_score_notes):
4904
+ if e[3] != 9:
4905
+ if patches[e[3]] == -1:
4906
+ patches[e[3]] = e[6]
4907
+ else:
4908
+ if patches[e[3]] != e[6]:
4909
+ if e[6] in patches:
4910
+ e[3] = patches.index(e[6])
4911
+ else:
4912
+ if -1 in patches:
4913
+ patches[patches.index(-1)] = e[6]
4914
+ else:
4915
+ overflow_idx = idx
4916
+ break
4917
+
4918
+ enhanced_score_notes_with_patch_changes.append(e)
4919
+
4920
+ #===========================================================================
4921
+
4922
+ overflow_patches = []
4923
+
4924
+ if overflow_idx != -1:
4925
+ for idx, e in enumerate(enhanced_score_notes[overflow_idx:]):
4926
+ if e[3] != 9:
4927
+ if e[6] not in patches:
4928
+ if e[6] not in overflow_patches:
4929
+ overflow_patches.append(e[6])
4930
+ enhanced_score_notes_with_patch_changes.append(['patch_change', e[1], e[3], e[6]])
4931
+ else:
4932
+ e[3] = patches.index(e[6])
4933
+
4934
+ enhanced_score_notes_with_patch_changes.append(e)
4935
+
4936
+ #===========================================================================
4937
+
4938
+ patches = [p if p != -1 else default_patch for p in patches]
4939
+
4940
+ patches[9] = drums_patch
4941
+
4942
+ #===========================================================================
4943
+
4944
+ if verbose:
4945
+ print('=' * 70)
4946
+ print('Composition patches')
4947
+ print('=' * 70)
4948
+ for c, p in enumerate(patches):
4949
+ print('Cha', str(c).zfill(2), '---', str(p).zfill(3), Number2patch[p])
4950
+ print('=' * 70)
4951
+
4952
+ if overflow_patches:
4953
+ print('Extra composition patches')
4954
+ print('=' * 70)
4955
+ for c, p in enumerate(overflow_patches):
4956
+ print(str(p).zfill(3), Number2patch[p])
4957
+ print('=' * 70)
4958
+
4959
+ return enhanced_score_notes_with_patch_changes, patches, overflow_patches
4960
+
4961
+ ###################################################################################
4962
+
4963
  # This is the end of the TMIDI X Python module
4964
 
4965
  ###################################################################################