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')
|
|
@@ -13918,6 +13918,145 @@ def chunk_by_threshold_mode(nums, threshold=0, normalize=False):
|
|
| 13918 |
|
| 13919 |
###################################################################################
|
| 13920 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13921 |
print('Module loaded!')
|
| 13922 |
print('=' * 70)
|
| 13923 |
print('Enjoy! :)')
|
|
|
|
| 51 |
|
| 52 |
###################################################################################
|
| 53 |
|
| 54 |
+
__version__ = "25.8.22"
|
| 55 |
|
| 56 |
print('=' * 70)
|
| 57 |
print('TMIDIX Python module')
|
|
|
|
| 13918 |
|
| 13919 |
###################################################################################
|
| 13920 |
|
| 13921 |
+
def proportional_adjust(values, target_sum, threshold):
|
| 13922 |
+
|
| 13923 |
+
n = len(values)
|
| 13924 |
+
locked_idx = [i for i, v in enumerate(values) if v < threshold]
|
| 13925 |
+
adj_idx = [i for i in range(n) if i not in locked_idx]
|
| 13926 |
+
|
| 13927 |
+
locked_sum = sum(values[i] for i in locked_idx)
|
| 13928 |
+
adj_original_sum = sum(values[i] for i in adj_idx)
|
| 13929 |
+
adj_target_sum = target_sum - locked_sum
|
| 13930 |
+
|
| 13931 |
+
if adj_target_sum < 0:
|
| 13932 |
+
print("target_sum is smaller than the sum of locked values")
|
| 13933 |
+
return None
|
| 13934 |
+
|
| 13935 |
+
if not adj_idx:
|
| 13936 |
+
if locked_sum == target_sum:
|
| 13937 |
+
return values.copy()
|
| 13938 |
+
|
| 13939 |
+
print("no entries >= threshold to adjust, but sums differ")
|
| 13940 |
+
return None
|
| 13941 |
+
|
| 13942 |
+
if adj_original_sum == 0:
|
| 13943 |
+
base = adj_target_sum // len(adj_idx)
|
| 13944 |
+
remainder = adj_target_sum - base * len(adj_idx)
|
| 13945 |
+
new_vals = values.copy()
|
| 13946 |
+
|
| 13947 |
+
for j, i in enumerate(sorted(adj_idx)):
|
| 13948 |
+
add = base + (1 if j >= len(adj_idx) - remainder else 0)
|
| 13949 |
+
new_vals[i] = values[i] + add
|
| 13950 |
+
|
| 13951 |
+
return new_vals
|
| 13952 |
+
|
| 13953 |
+
factor = adj_target_sum / adj_original_sum
|
| 13954 |
+
scaled = {i: values[i] * factor for i in adj_idx}
|
| 13955 |
+
floored = {i: math.floor(scaled[i]) for i in adj_idx}
|
| 13956 |
+
floor_sum = sum(floored.values())
|
| 13957 |
+
|
| 13958 |
+
remainder = adj_target_sum - floor_sum
|
| 13959 |
+
|
| 13960 |
+
fracs = sorted(
|
| 13961 |
+
((scaled[i] - floored[i], i) for i in adj_idx),
|
| 13962 |
+
key=lambda x: (x[0], x[1]),
|
| 13963 |
+
reverse=True
|
| 13964 |
+
)
|
| 13965 |
+
|
| 13966 |
+
for frac, i in fracs[:remainder]:
|
| 13967 |
+
floored[i] += 1
|
| 13968 |
+
|
| 13969 |
+
result = values.copy()
|
| 13970 |
+
|
| 13971 |
+
for i in adj_idx:
|
| 13972 |
+
result[i] = floored[i]
|
| 13973 |
+
|
| 13974 |
+
return result
|
| 13975 |
+
|
| 13976 |
+
###################################################################################
|
| 13977 |
+
|
| 13978 |
+
def advanced_align_escore_notes_to_bars(escore_notes,
|
| 13979 |
+
bar_dtime=200,
|
| 13980 |
+
dtimes_adj_thresh=4,
|
| 13981 |
+
min_dur_gap=0
|
| 13982 |
+
):
|
| 13983 |
+
|
| 13984 |
+
#========================================================
|
| 13985 |
+
|
| 13986 |
+
escore_notes = recalculate_score_timings(escore_notes)
|
| 13987 |
+
|
| 13988 |
+
cscore = chordify_score([1000, escore_notes])
|
| 13989 |
+
|
| 13990 |
+
#========================================================
|
| 13991 |
+
|
| 13992 |
+
dtimes = [0] + [min(199, b[1]-a[1]) for a, b in zip(escore_notes[:-1], escore_notes[1:]) if b[1]-a[1] != 0]
|
| 13993 |
+
|
| 13994 |
+
score_times = sorted(set([e[1] for e in escore_notes]))
|
| 13995 |
+
|
| 13996 |
+
#========================================================
|
| 13997 |
+
|
| 13998 |
+
dtimes_chunks = []
|
| 13999 |
+
|
| 14000 |
+
time = 0
|
| 14001 |
+
dtime = []
|
| 14002 |
+
|
| 14003 |
+
for i, dt in enumerate(dtimes):
|
| 14004 |
+
time += dt
|
| 14005 |
+
dtime.append(dt)
|
| 14006 |
+
|
| 14007 |
+
if time >= bar_dtime:
|
| 14008 |
+
dtimes_chunks.append(dtime)
|
| 14009 |
+
|
| 14010 |
+
time = 0
|
| 14011 |
+
dtime = []
|
| 14012 |
+
|
| 14013 |
+
dtimes_chunks.append(dtime)
|
| 14014 |
+
|
| 14015 |
+
#========================================================
|
| 14016 |
+
|
| 14017 |
+
fixed_times = []
|
| 14018 |
+
|
| 14019 |
+
time = 0
|
| 14020 |
+
|
| 14021 |
+
for i, dt in enumerate(dtimes_chunks):
|
| 14022 |
+
|
| 14023 |
+
adj_dt = proportional_adjust(dt,
|
| 14024 |
+
bar_dtime,
|
| 14025 |
+
dtimes_adj_thresh
|
| 14026 |
+
)
|
| 14027 |
+
|
| 14028 |
+
for t in adj_dt:
|
| 14029 |
+
|
| 14030 |
+
time += t
|
| 14031 |
+
|
| 14032 |
+
fixed_times.append(time)
|
| 14033 |
+
|
| 14034 |
+
#========================================================
|
| 14035 |
+
|
| 14036 |
+
output_score = []
|
| 14037 |
+
|
| 14038 |
+
for i, c in enumerate(cscore):
|
| 14039 |
+
|
| 14040 |
+
cc = copy.deepcopy(c)
|
| 14041 |
+
time = fixed_times[i]
|
| 14042 |
+
|
| 14043 |
+
for e in cc:
|
| 14044 |
+
e[1] = time
|
| 14045 |
+
|
| 14046 |
+
output_score.append(e)
|
| 14047 |
+
|
| 14048 |
+
#========================================================
|
| 14049 |
+
|
| 14050 |
+
output_score = fix_escore_notes_durations(output_score,
|
| 14051 |
+
min_notes_gap=min_dur_gap
|
| 14052 |
+
)
|
| 14053 |
+
|
| 14054 |
+
#========================================================
|
| 14055 |
+
|
| 14056 |
+
return output_score
|
| 14057 |
+
|
| 14058 |
+
###################################################################################
|
| 14059 |
+
|
| 14060 |
print('Module loaded!')
|
| 14061 |
print('=' * 70)
|
| 14062 |
print('Enjoy! :)')
|