Upload TMIDIX.py
Browse files
TMIDIX.py
CHANGED
@@ -51,7 +51,7 @@ r'''############################################################################
|
|
51 |
|
52 |
###################################################################################
|
53 |
|
54 |
-
__version__ = "25.
|
55 |
|
56 |
print('=' * 70)
|
57 |
print('TMIDIX Python module')
|
@@ -1513,6 +1513,9 @@ import hashlib
|
|
1513 |
|
1514 |
from array import array
|
1515 |
|
|
|
|
|
|
|
1516 |
###################################################################################
|
1517 |
#
|
1518 |
# Original TMIDI Tegridy helper functions
|
@@ -13132,7 +13135,7 @@ def fix_escore_notes_durations(escore_notes,
|
|
13132 |
elif len(g) == 2:
|
13133 |
|
13134 |
if g[0][times_idx]+g[0][durs_idx] >= g[1][times_idx]:
|
13135 |
-
g[0][durs_idx] = max(1, g[1][times_idx] - g[0][times_idx] -
|
13136 |
|
13137 |
merged_score.extend(g)
|
13138 |
|
@@ -13240,6 +13243,179 @@ def remove_duplicate_pitches_from_escore_notes(escore_notes,
|
|
13240 |
return new_escore
|
13241 |
|
13242 |
###################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13243 |
|
13244 |
print('Module loaded!')
|
13245 |
print('=' * 70)
|
|
|
51 |
|
52 |
###################################################################################
|
53 |
|
54 |
+
__version__ = "25.7.5"
|
55 |
|
56 |
print('=' * 70)
|
57 |
print('TMIDIX Python module')
|
|
|
1513 |
|
1514 |
from array import array
|
1515 |
|
1516 |
+
from pathlib import Path
|
1517 |
+
from fnmatch import fnmatch
|
1518 |
+
|
1519 |
###################################################################################
|
1520 |
#
|
1521 |
# Original TMIDI Tegridy helper functions
|
|
|
13135 |
elif len(g) == 2:
|
13136 |
|
13137 |
if g[0][times_idx]+g[0][durs_idx] >= g[1][times_idx]:
|
13138 |
+
g[0][durs_idx] = max(1, g[1][times_idx] - g[0][times_idx] - min_notes_gap)
|
13139 |
|
13140 |
merged_score.extend(g)
|
13141 |
|
|
|
13243 |
return new_escore
|
13244 |
|
13245 |
###################################################################################
|
13246 |
+
|
13247 |
+
def chunks_shuffle(lst,
|
13248 |
+
min_len=1,
|
13249 |
+
max_len=3,
|
13250 |
+
seed=None
|
13251 |
+
):
|
13252 |
+
|
13253 |
+
rnd = random.Random(seed)
|
13254 |
+
chunks = []
|
13255 |
+
i, n = 0, len(lst)
|
13256 |
+
|
13257 |
+
while i < n:
|
13258 |
+
size = rnd.randint(min_len, max_len)
|
13259 |
+
size = min(size, n - i)
|
13260 |
+
chunks.append(lst[i : i + size])
|
13261 |
+
i += size
|
13262 |
+
|
13263 |
+
rnd.shuffle(chunks)
|
13264 |
+
|
13265 |
+
flattened = []
|
13266 |
+
for chunk in chunks:
|
13267 |
+
flattened.extend(chunk)
|
13268 |
+
|
13269 |
+
return flattened
|
13270 |
+
|
13271 |
+
###################################################################################
|
13272 |
+
|
13273 |
+
def convert_bytes_in_nested_list(lst,
|
13274 |
+
encoding='utf-8',
|
13275 |
+
errors='ignore',
|
13276 |
+
return_changed_events_count=False
|
13277 |
+
):
|
13278 |
+
|
13279 |
+
new_list = []
|
13280 |
+
|
13281 |
+
ce_count = 0
|
13282 |
+
|
13283 |
+
for item in lst:
|
13284 |
+
if isinstance(item, list):
|
13285 |
+
new_list.append(convert_bytes_in_nested_list(item))
|
13286 |
+
|
13287 |
+
elif isinstance(item, bytes):
|
13288 |
+
new_list.append(item.decode(encoding, errors=errors))
|
13289 |
+
ce_count += 1
|
13290 |
+
|
13291 |
+
else:
|
13292 |
+
new_list.append(item)
|
13293 |
+
|
13294 |
+
if return_changed_events_count:
|
13295 |
+
return new_list, ce_count
|
13296 |
+
|
13297 |
+
else:
|
13298 |
+
return new_list
|
13299 |
+
|
13300 |
+
###################################################################################
|
13301 |
+
|
13302 |
+
def find_deepest_midi_dirs(roots,
|
13303 |
+
marker_file="midi_score.mid",
|
13304 |
+
suffixes=None,
|
13305 |
+
randomize=False,
|
13306 |
+
seed=None,
|
13307 |
+
verbose=False
|
13308 |
+
):
|
13309 |
+
|
13310 |
+
try:
|
13311 |
+
iter(roots)
|
13312 |
+
if isinstance(roots, (str, Path)):
|
13313 |
+
root_list = [roots]
|
13314 |
+
else:
|
13315 |
+
root_list = list(roots)
|
13316 |
+
|
13317 |
+
except TypeError:
|
13318 |
+
root_list = [roots]
|
13319 |
+
|
13320 |
+
if isinstance(marker_file, (list, tuple)):
|
13321 |
+
patterns = [p.lower() for p in marker_file if p]
|
13322 |
+
|
13323 |
+
else:
|
13324 |
+
patterns = [marker_file.lower()] if marker_file else []
|
13325 |
+
|
13326 |
+
allowed = {s.lower() for s in (suffixes or ['.mid', '.midi', '.kar'])}
|
13327 |
+
|
13328 |
+
if verbose:
|
13329 |
+
print("Settings:")
|
13330 |
+
print(" Roots:", [str(r) for r in root_list])
|
13331 |
+
print(" Marker patterns:", patterns or "<no marker filter>")
|
13332 |
+
print(" Allowed suffixes:", allowed)
|
13333 |
+
print(f" Randomize={randomize}, Seed={seed}")
|
13334 |
+
|
13335 |
+
results = defaultdict(list)
|
13336 |
+
rng = random.Random(seed)
|
13337 |
+
|
13338 |
+
for root in root_list:
|
13339 |
+
|
13340 |
+
root_path = Path(root)
|
13341 |
+
|
13342 |
+
if not root_path.is_dir():
|
13343 |
+
print(f"Warning: '{root_path}' is not a valid directory, skipping.")
|
13344 |
+
continue
|
13345 |
+
|
13346 |
+
if verbose:
|
13347 |
+
print(f"\nScanning root: {str(root_path)}")
|
13348 |
+
|
13349 |
+
all_dirs = list(root_path.rglob("*"))
|
13350 |
+
dirs_iter = tqdm.tqdm(all_dirs, desc=f"Dirs in {root_path.name}", disable=not verbose)
|
13351 |
+
|
13352 |
+
for dirpath in dirs_iter:
|
13353 |
+
if not dirpath.is_dir():
|
13354 |
+
continue
|
13355 |
+
|
13356 |
+
children = list(dirpath.iterdir())
|
13357 |
+
if any(child.is_dir() for child in children):
|
13358 |
+
if verbose:
|
13359 |
+
print(f"Skipping non-leaf: {str(dirpath)}")
|
13360 |
+
continue
|
13361 |
+
|
13362 |
+
files = [f for f in children if f.is_file()]
|
13363 |
+
names = [f.name.lower() for f in files]
|
13364 |
+
|
13365 |
+
if patterns:
|
13366 |
+
matched = any(fnmatch(name, pat) for name in names for pat in patterns)
|
13367 |
+
if not matched:
|
13368 |
+
if verbose:
|
13369 |
+
print(f"No marker in: {str(dirpath)}")
|
13370 |
+
continue
|
13371 |
+
|
13372 |
+
if verbose:
|
13373 |
+
print(f"Marker found in: {str(dirpath)}")
|
13374 |
+
|
13375 |
+
else:
|
13376 |
+
if verbose:
|
13377 |
+
print(f"Including leaf (no marker): {str(dirpath)}")
|
13378 |
+
|
13379 |
+
for f in files:
|
13380 |
+
if f.suffix.lower() in allowed:
|
13381 |
+
results[str(dirpath)].append(str(f))
|
13382 |
+
|
13383 |
+
if verbose:
|
13384 |
+
print(f" Collected: {f.name}")
|
13385 |
+
|
13386 |
+
all_leaves = list(results.keys())
|
13387 |
+
if randomize:
|
13388 |
+
if verbose:
|
13389 |
+
print("\nShuffling leaf directories")
|
13390 |
+
|
13391 |
+
rng.shuffle(all_leaves)
|
13392 |
+
|
13393 |
+
else:
|
13394 |
+
all_leaves.sort()
|
13395 |
+
|
13396 |
+
final_dict = {}
|
13397 |
+
|
13398 |
+
for leaf in all_leaves:
|
13399 |
+
file_list = results[leaf][:]
|
13400 |
+
if randomize:
|
13401 |
+
if verbose:
|
13402 |
+
print(f"Shuffling files in: {leaf}")
|
13403 |
+
|
13404 |
+
rng.shuffle(file_list)
|
13405 |
+
|
13406 |
+
else:
|
13407 |
+
file_list.sort()
|
13408 |
+
|
13409 |
+
final_dict[leaf] = file_list
|
13410 |
+
|
13411 |
+
if verbose:
|
13412 |
+
print("\nScan complete. Found directories:")
|
13413 |
+
for d, fl in final_dict.items():
|
13414 |
+
print(f" {d} -> {len(fl)} files")
|
13415 |
+
|
13416 |
+
return final_dict
|
13417 |
+
|
13418 |
+
###################################################################################
|
13419 |
|
13420 |
print('Module loaded!')
|
13421 |
print('=' * 70)
|