Upload TMIDIX.py
Browse files
TMIDIX.py
CHANGED
|
@@ -51,7 +51,7 @@ r'''############################################################################
|
|
| 51 |
|
| 52 |
###################################################################################
|
| 53 |
|
| 54 |
-
__version__ = "25.8.
|
| 55 |
|
| 56 |
print('=' * 70)
|
| 57 |
print('TMIDIX Python module')
|
|
@@ -1485,10 +1485,12 @@ import multiprocessing
|
|
| 1485 |
|
| 1486 |
from itertools import zip_longest
|
| 1487 |
from itertools import groupby
|
|
|
|
| 1488 |
|
| 1489 |
from collections import Counter
|
| 1490 |
from collections import defaultdict
|
| 1491 |
from collections import OrderedDict
|
|
|
|
| 1492 |
|
| 1493 |
from operator import itemgetter
|
| 1494 |
|
|
@@ -8056,7 +8058,7 @@ def solo_piano_escore_notes(escore_notes,
|
|
| 8056 |
keep_drums=False,
|
| 8057 |
):
|
| 8058 |
|
| 8059 |
-
cscore = chordify_score([1000, escore_notes])
|
| 8060 |
|
| 8061 |
sp_escore_notes = []
|
| 8062 |
|
|
@@ -11400,7 +11402,7 @@ def multiprocessing_wrapper(function, data_list, verbose=True):
|
|
| 11400 |
|
| 11401 |
results = []
|
| 11402 |
|
| 11403 |
-
for result in tqdm.tqdm(pool.
|
| 11404 |
total=len(data_list),
|
| 11405 |
disable=not verbose
|
| 11406 |
):
|
|
@@ -14057,6 +14059,380 @@ def advanced_align_escore_notes_to_bars(escore_notes,
|
|
| 14057 |
|
| 14058 |
###################################################################################
|
| 14059 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14060 |
print('Module loaded!')
|
| 14061 |
print('=' * 70)
|
| 14062 |
print('Enjoy! :)')
|
|
|
|
| 51 |
|
| 52 |
###################################################################################
|
| 53 |
|
| 54 |
+
__version__ = "25.8.27"
|
| 55 |
|
| 56 |
print('=' * 70)
|
| 57 |
print('TMIDIX Python module')
|
|
|
|
| 1485 |
|
| 1486 |
from itertools import zip_longest
|
| 1487 |
from itertools import groupby
|
| 1488 |
+
from itertools import cycle
|
| 1489 |
|
| 1490 |
from collections import Counter
|
| 1491 |
from collections import defaultdict
|
| 1492 |
from collections import OrderedDict
|
| 1493 |
+
from collections import deque
|
| 1494 |
|
| 1495 |
from operator import itemgetter
|
| 1496 |
|
|
|
|
| 8058 |
keep_drums=False,
|
| 8059 |
):
|
| 8060 |
|
| 8061 |
+
cscore = chordify_score([1000, copy.deepcopy(escore_notes)])
|
| 8062 |
|
| 8063 |
sp_escore_notes = []
|
| 8064 |
|
|
|
|
| 11402 |
|
| 11403 |
results = []
|
| 11404 |
|
| 11405 |
+
for result in tqdm.tqdm(pool.imap(function, data_list),
|
| 11406 |
total=len(data_list),
|
| 11407 |
disable=not verbose
|
| 11408 |
):
|
|
|
|
| 14059 |
|
| 14060 |
###################################################################################
|
| 14061 |
|
| 14062 |
+
def check_monophonic_melody(escore_notes,
|
| 14063 |
+
times_idx=1,
|
| 14064 |
+
durs_idx=2
|
| 14065 |
+
):
|
| 14066 |
+
|
| 14067 |
+
bcount = 0
|
| 14068 |
+
|
| 14069 |
+
for i in range(len(escore_notes)-1):
|
| 14070 |
+
if escore_notes[i][times_idx]+escore_notes[i][durs_idx] > escore_notes[i+1][times_idx]:
|
| 14071 |
+
bcount += 1
|
| 14072 |
+
|
| 14073 |
+
return bcount / len(escore_notes)
|
| 14074 |
+
|
| 14075 |
+
###################################################################################
|
| 14076 |
+
|
| 14077 |
+
def longest_common_chunk(list1, list2):
|
| 14078 |
+
|
| 14079 |
+
base, mod = 257, 10**9 + 7
|
| 14080 |
+
max_len = min(len(list1), len(list2))
|
| 14081 |
+
|
| 14082 |
+
def get_hashes(seq, size):
|
| 14083 |
+
|
| 14084 |
+
h, power = 0, 1
|
| 14085 |
+
hashes = set()
|
| 14086 |
+
|
| 14087 |
+
for i in range(size):
|
| 14088 |
+
h = (h * base + seq[i]) % mod
|
| 14089 |
+
power = (power * base) % mod
|
| 14090 |
+
|
| 14091 |
+
hashes.add(h)
|
| 14092 |
+
|
| 14093 |
+
for i in range(size, len(seq)):
|
| 14094 |
+
h = (h * base - seq[i - size] * power + seq[i]) % mod
|
| 14095 |
+
hashes.add(h)
|
| 14096 |
+
|
| 14097 |
+
return hashes
|
| 14098 |
+
|
| 14099 |
+
def find_match(size):
|
| 14100 |
+
|
| 14101 |
+
hashes2 = get_hashes(list2, size)
|
| 14102 |
+
h, power = 0, 1
|
| 14103 |
+
|
| 14104 |
+
for i in range(size):
|
| 14105 |
+
h = (h * base + list1[i]) % mod
|
| 14106 |
+
power = (power * base) % mod
|
| 14107 |
+
|
| 14108 |
+
if h in hashes2:
|
| 14109 |
+
return list1[:size]
|
| 14110 |
+
|
| 14111 |
+
for i in range(size, len(list1)):
|
| 14112 |
+
h = (h * base - list1[i - size] * power + list1[i]) % mod
|
| 14113 |
+
if h in hashes2:
|
| 14114 |
+
return list1[i - size + 1:i + 1]
|
| 14115 |
+
|
| 14116 |
+
return []
|
| 14117 |
+
|
| 14118 |
+
left, right = 0, max_len
|
| 14119 |
+
result = []
|
| 14120 |
+
|
| 14121 |
+
while left <= right:
|
| 14122 |
+
mid = (left + right) // 2
|
| 14123 |
+
chunk = find_match(mid)
|
| 14124 |
+
|
| 14125 |
+
if chunk:
|
| 14126 |
+
result = chunk
|
| 14127 |
+
left = mid + 1
|
| 14128 |
+
else:
|
| 14129 |
+
|
| 14130 |
+
right = mid - 1
|
| 14131 |
+
|
| 14132 |
+
return result
|
| 14133 |
+
|
| 14134 |
+
###################################################################################
|
| 14135 |
+
|
| 14136 |
+
def detect_plateaus(data, min_len=2, tol=0.0):
|
| 14137 |
+
|
| 14138 |
+
plateaus = []
|
| 14139 |
+
n = len(data)
|
| 14140 |
+
if n < min_len:
|
| 14141 |
+
return plateaus
|
| 14142 |
+
|
| 14143 |
+
min_deque = deque()
|
| 14144 |
+
max_deque = deque()
|
| 14145 |
+
|
| 14146 |
+
start = 0
|
| 14147 |
+
idx = 0
|
| 14148 |
+
|
| 14149 |
+
while idx < n:
|
| 14150 |
+
v = data[idx]
|
| 14151 |
+
|
| 14152 |
+
if not isinstance(v, (int, float)) or math.isnan(v):
|
| 14153 |
+
|
| 14154 |
+
if idx - start >= min_len:
|
| 14155 |
+
plateaus.append(data[start:idx])
|
| 14156 |
+
|
| 14157 |
+
idx += 1
|
| 14158 |
+
start = idx
|
| 14159 |
+
min_deque.clear()
|
| 14160 |
+
max_deque.clear()
|
| 14161 |
+
|
| 14162 |
+
continue
|
| 14163 |
+
|
| 14164 |
+
while max_deque and data[max_deque[-1]] <= v:
|
| 14165 |
+
max_deque.pop()
|
| 14166 |
+
|
| 14167 |
+
max_deque.append(idx)
|
| 14168 |
+
|
| 14169 |
+
while min_deque and data[min_deque[-1]] >= v:
|
| 14170 |
+
min_deque.pop()
|
| 14171 |
+
|
| 14172 |
+
min_deque.append(idx)
|
| 14173 |
+
|
| 14174 |
+
if data[max_deque[0]] - data[min_deque[0]] > tol:
|
| 14175 |
+
|
| 14176 |
+
if idx - start >= min_len:
|
| 14177 |
+
plateaus.append(data[start:idx])
|
| 14178 |
+
|
| 14179 |
+
start = idx
|
| 14180 |
+
|
| 14181 |
+
min_deque.clear()
|
| 14182 |
+
max_deque.clear()
|
| 14183 |
+
|
| 14184 |
+
max_deque.append(idx)
|
| 14185 |
+
min_deque.append(idx)
|
| 14186 |
+
|
| 14187 |
+
idx += 1
|
| 14188 |
+
|
| 14189 |
+
if n - start >= min_len:
|
| 14190 |
+
plateaus.append(data[start:n])
|
| 14191 |
+
|
| 14192 |
+
return plateaus
|
| 14193 |
+
|
| 14194 |
+
###################################################################################
|
| 14195 |
+
|
| 14196 |
+
def alpha_str_to_toks(s, shift=0, add_seos=False):
|
| 14197 |
+
|
| 14198 |
+
tokens = []
|
| 14199 |
+
|
| 14200 |
+
if add_seos:
|
| 14201 |
+
tokens = [53+shift]
|
| 14202 |
+
|
| 14203 |
+
for char in s:
|
| 14204 |
+
if char == ' ':
|
| 14205 |
+
tokens.append(52+shift)
|
| 14206 |
+
|
| 14207 |
+
elif char.isalpha():
|
| 14208 |
+
base = 0 if char.isupper() else 26
|
| 14209 |
+
offset = ord(char.upper()) - ord('A')
|
| 14210 |
+
token = (base + offset + shift) % 52 # wrap A–Z/a–z
|
| 14211 |
+
tokens.append(token)
|
| 14212 |
+
|
| 14213 |
+
if add_seos:
|
| 14214 |
+
tokens.append(53+shift)
|
| 14215 |
+
|
| 14216 |
+
return tokens
|
| 14217 |
+
|
| 14218 |
+
###################################################################################
|
| 14219 |
+
|
| 14220 |
+
def toks_to_alpha_str(tokens, shift=0, sep=''):
|
| 14221 |
+
|
| 14222 |
+
chars = []
|
| 14223 |
+
|
| 14224 |
+
for token in tokens:
|
| 14225 |
+
if token == 53+shift:
|
| 14226 |
+
continue
|
| 14227 |
+
|
| 14228 |
+
elif token == 52+shift:
|
| 14229 |
+
chars.append(' ')
|
| 14230 |
+
|
| 14231 |
+
elif 0 <= token <= 25:
|
| 14232 |
+
original = (token - shift) % 52
|
| 14233 |
+
chars.append(chr(ord('A') + original))
|
| 14234 |
+
|
| 14235 |
+
elif 26 <= token <= 51:
|
| 14236 |
+
original = (token - shift) % 52
|
| 14237 |
+
chars.append(chr(ord('a') + (original - 26)))
|
| 14238 |
+
|
| 14239 |
+
return sep.join(chars)
|
| 14240 |
+
|
| 14241 |
+
###################################################################################
|
| 14242 |
+
|
| 14243 |
+
def insert_caps_newlines(text):
|
| 14244 |
+
|
| 14245 |
+
if bool(re.search(r'\b[A-Z][a-z]+\b', text)):
|
| 14246 |
+
pattern = re.compile(r'\s+(?=[A-Z])')
|
| 14247 |
+
|
| 14248 |
+
return pattern.sub('\n', text)
|
| 14249 |
+
|
| 14250 |
+
###################################################################################
|
| 14251 |
+
|
| 14252 |
+
def insert_newlines(text, every=4):
|
| 14253 |
+
|
| 14254 |
+
count = 0
|
| 14255 |
+
result = []
|
| 14256 |
+
|
| 14257 |
+
for char in text:
|
| 14258 |
+
result.append(char)
|
| 14259 |
+
|
| 14260 |
+
if char == '\n':
|
| 14261 |
+
count += 1
|
| 14262 |
+
|
| 14263 |
+
if count % every == 0:
|
| 14264 |
+
result.append('\n')
|
| 14265 |
+
|
| 14266 |
+
return ''.join(result)
|
| 14267 |
+
|
| 14268 |
+
###################################################################################
|
| 14269 |
+
|
| 14270 |
+
def symmetric_match_ratio(list_a, list_b, threshold=0):
|
| 14271 |
+
|
| 14272 |
+
a_sorted = sorted(list_a)
|
| 14273 |
+
b_sorted = sorted(list_b)
|
| 14274 |
+
|
| 14275 |
+
i, j = 0, 0
|
| 14276 |
+
matches = 0
|
| 14277 |
+
|
| 14278 |
+
used_a = set()
|
| 14279 |
+
used_b = set()
|
| 14280 |
+
|
| 14281 |
+
while i < len(a_sorted) and j < len(b_sorted):
|
| 14282 |
+
diff = abs(a_sorted[i] - b_sorted[j])
|
| 14283 |
+
|
| 14284 |
+
if diff <= threshold:
|
| 14285 |
+
matches += 1
|
| 14286 |
+
used_a.add(i)
|
| 14287 |
+
used_b.add(j)
|
| 14288 |
+
i += 1
|
| 14289 |
+
j += 1
|
| 14290 |
+
|
| 14291 |
+
elif a_sorted[i] < b_sorted[j]:
|
| 14292 |
+
i += 1
|
| 14293 |
+
|
| 14294 |
+
else:
|
| 14295 |
+
j += 1
|
| 14296 |
+
|
| 14297 |
+
avg_len = (len(list_a) + len(list_b)) / 2
|
| 14298 |
+
|
| 14299 |
+
return matches / avg_len if avg_len > 0 else 0.0
|
| 14300 |
+
|
| 14301 |
+
###################################################################################
|
| 14302 |
+
|
| 14303 |
+
def escore_notes_to_chords(escore_notes,
|
| 14304 |
+
use_full_chords=False,
|
| 14305 |
+
convert_pitches=True,
|
| 14306 |
+
shift_chords=False,
|
| 14307 |
+
return_tones_chords=False
|
| 14308 |
+
):
|
| 14309 |
+
|
| 14310 |
+
if use_full_chords:
|
| 14311 |
+
CHORDS = ALL_CHORDS_FULL
|
| 14312 |
+
|
| 14313 |
+
else:
|
| 14314 |
+
CHORDS = ALL_CHORDS_SORTED
|
| 14315 |
+
|
| 14316 |
+
sp_score = solo_piano_escore_notes(escore_notes)
|
| 14317 |
+
|
| 14318 |
+
cscore = chordify_score([1000, sp_score])
|
| 14319 |
+
|
| 14320 |
+
chords = []
|
| 14321 |
+
|
| 14322 |
+
for c in cscore:
|
| 14323 |
+
pitches = sorted(set([e[4] for e in c]))
|
| 14324 |
+
|
| 14325 |
+
tones_chord = sorted(set([p % 12 for p in pitches]))
|
| 14326 |
+
|
| 14327 |
+
if tones_chord not in CHORDS:
|
| 14328 |
+
tones_chord = check_and_fix_tones_chord(tones_chord,
|
| 14329 |
+
use_full_chords=use_full_chords
|
| 14330 |
+
)
|
| 14331 |
+
if return_tones_chords:
|
| 14332 |
+
if convert_pitches:
|
| 14333 |
+
chords.append(tones_chord)
|
| 14334 |
+
|
| 14335 |
+
else:
|
| 14336 |
+
if len(pitches) > 1:
|
| 14337 |
+
chords.append(tones_chord)
|
| 14338 |
+
|
| 14339 |
+
else:
|
| 14340 |
+
chords.append([-pitches[0]])
|
| 14341 |
+
|
| 14342 |
+
else:
|
| 14343 |
+
cho_tok = CHORDS.index(tones_chord)
|
| 14344 |
+
if convert_pitches:
|
| 14345 |
+
if shift_chords:
|
| 14346 |
+
if len(pitches) > 1:
|
| 14347 |
+
chords.append(cho_tok+12)
|
| 14348 |
+
|
| 14349 |
+
else:
|
| 14350 |
+
chords.append(pitches[0] % 12)
|
| 14351 |
+
|
| 14352 |
+
else:
|
| 14353 |
+
chords.append(cho_tok)
|
| 14354 |
+
|
| 14355 |
+
else:
|
| 14356 |
+
if len(pitches) > 1:
|
| 14357 |
+
chords.append(cho_tok+128)
|
| 14358 |
+
|
| 14359 |
+
else:
|
| 14360 |
+
chords.append(pitches[0])
|
| 14361 |
+
|
| 14362 |
+
return chords
|
| 14363 |
+
|
| 14364 |
+
###################################################################################
|
| 14365 |
+
|
| 14366 |
+
def replace_chords_in_escore_notes(escore_notes,
|
| 14367 |
+
chords_list=[-1],
|
| 14368 |
+
use_full_chords=False,
|
| 14369 |
+
use_shifted_chords=False
|
| 14370 |
+
):
|
| 14371 |
+
|
| 14372 |
+
if use_full_chords:
|
| 14373 |
+
CHORDS = ALL_CHORDS_FULL
|
| 14374 |
+
|
| 14375 |
+
else:
|
| 14376 |
+
CHORDS = ALL_CHORDS_SORTED
|
| 14377 |
+
|
| 14378 |
+
if use_shifted_chords:
|
| 14379 |
+
shift = 12
|
| 14380 |
+
|
| 14381 |
+
else:
|
| 14382 |
+
shift = 0
|
| 14383 |
+
|
| 14384 |
+
if min(chords_list) >= 0 and max(chords_list) <= len(CHORDS)+shift:
|
| 14385 |
+
|
| 14386 |
+
chords_list_iter = cycle(chords_list)
|
| 14387 |
+
|
| 14388 |
+
nd_score = [e for e in escore_notes if e[3] != 9]
|
| 14389 |
+
d_score = [e for e in escore_notes if e[3] == 9]
|
| 14390 |
+
|
| 14391 |
+
cscore = chordify_score([1000, nd_score])
|
| 14392 |
+
|
| 14393 |
+
new_score = []
|
| 14394 |
+
|
| 14395 |
+
for i, c in enumerate(cscore):
|
| 14396 |
+
|
| 14397 |
+
cur_chord = next(chords_list_iter)
|
| 14398 |
+
|
| 14399 |
+
cc = copy.deepcopy(c)
|
| 14400 |
+
|
| 14401 |
+
if use_shifted_chords:
|
| 14402 |
+
if cur_chord < 12:
|
| 14403 |
+
sub_tones_chord = [cur_chord]
|
| 14404 |
+
|
| 14405 |
+
else:
|
| 14406 |
+
sub_tones_chord = CHORDS[cur_chord-12]
|
| 14407 |
+
else:
|
| 14408 |
+
sub_tones_chord = CHORDS[cur_chord]
|
| 14409 |
+
|
| 14410 |
+
stcho = cycle(sub_tones_chord)
|
| 14411 |
+
|
| 14412 |
+
if len(sub_tones_chord) > len(c):
|
| 14413 |
+
cc = [copy.deepcopy(e) for e in cc for _ in range(len(sub_tones_chord))]
|
| 14414 |
+
|
| 14415 |
+
pseen = []
|
| 14416 |
+
|
| 14417 |
+
for e in cc:
|
| 14418 |
+
st = next(stcho)
|
| 14419 |
+
new_pitch = ((e[4] // 12) * 12) + st
|
| 14420 |
+
|
| 14421 |
+
if [new_pitch, e[6]] not in pseen:
|
| 14422 |
+
e[4] = new_pitch
|
| 14423 |
+
|
| 14424 |
+
new_score.append(e)
|
| 14425 |
+
pseen.append([new_pitch, e[6]])
|
| 14426 |
+
|
| 14427 |
+
final_score = sorted(new_score+d_score, key=lambda x: x[1])
|
| 14428 |
+
|
| 14429 |
+
return final_score
|
| 14430 |
+
|
| 14431 |
+
else:
|
| 14432 |
+
return []
|
| 14433 |
+
|
| 14434 |
+
###################################################################################
|
| 14435 |
+
|
| 14436 |
print('Module loaded!')
|
| 14437 |
print('=' * 70)
|
| 14438 |
print('Enjoy! :)')
|