Upload TMIDIX.py
Browse files
TMIDIX.py
CHANGED
|
@@ -12,14 +12,14 @@ r'''############################################################################
|
|
| 12 |
#
|
| 13 |
# Project Los Angeles
|
| 14 |
#
|
| 15 |
-
# Tegridy Code
|
| 16 |
#
|
| 17 |
# https://github.com/Tegridy-Code/Project-Los-Angeles
|
| 18 |
#
|
| 19 |
#
|
| 20 |
###################################################################################
|
| 21 |
###################################################################################
|
| 22 |
-
# Copyright
|
| 23 |
#
|
| 24 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 25 |
# you may not use this file except in compliance with the License.
|
|
@@ -51,7 +51,7 @@ r'''############################################################################
|
|
| 51 |
|
| 52 |
###################################################################################
|
| 53 |
|
| 54 |
-
__version__ = "
|
| 55 |
|
| 56 |
print('=' * 70)
|
| 57 |
print('TMIDIX Python module')
|
|
@@ -1948,7 +1948,7 @@ def Tegridy_File_Time_Stamp(input_file_name='File_Created_on_', ext = ''):
|
|
| 1948 |
|
| 1949 |
###################################################################################
|
| 1950 |
|
| 1951 |
-
def Tegridy_Any_Pickle_File_Writer(Data, input_file_name='TMIDI_Pickle_File'):
|
| 1952 |
|
| 1953 |
'''Tegridy Pickle File Writer
|
| 1954 |
|
|
@@ -1959,23 +1959,27 @@ def Tegridy_Any_Pickle_File_Writer(Data, input_file_name='TMIDI_Pickle_File'):
|
|
| 1959 |
|
| 1960 |
Project Los Angeles
|
| 1961 |
Tegridy Code 2021'''
|
| 1962 |
-
|
| 1963 |
-
|
|
|
|
| 1964 |
|
| 1965 |
full_path_to_output_dataset_to = input_file_name + '.pickle'
|
| 1966 |
|
| 1967 |
if os.path.exists(full_path_to_output_dataset_to):
|
| 1968 |
os.remove(full_path_to_output_dataset_to)
|
| 1969 |
-
|
|
|
|
| 1970 |
else:
|
| 1971 |
-
|
|
|
|
| 1972 |
|
| 1973 |
with open(full_path_to_output_dataset_to, 'wb') as filehandle:
|
| 1974 |
# store the data as binary data stream
|
| 1975 |
pickle.dump(Data, filehandle, protocol=pickle.HIGHEST_PROTOCOL)
|
| 1976 |
|
| 1977 |
-
|
| 1978 |
-
|
|
|
|
| 1979 |
|
| 1980 |
###################################################################################
|
| 1981 |
|
|
@@ -13315,6 +13319,136 @@ def add_expressive_melody_to_enhanced_score_notes(escore_notes,
|
|
| 13315 |
return song_f
|
| 13316 |
|
| 13317 |
###################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13318 |
|
| 13319 |
def list_md5_hash(ints_list):
|
| 13320 |
|
|
|
|
| 12 |
#
|
| 13 |
# Project Los Angeles
|
| 14 |
#
|
| 15 |
+
# Tegridy Code 2026
|
| 16 |
#
|
| 17 |
# https://github.com/Tegridy-Code/Project-Los-Angeles
|
| 18 |
#
|
| 19 |
#
|
| 20 |
###################################################################################
|
| 21 |
###################################################################################
|
| 22 |
+
# Copyright 2026 Project Los Angeles / Tegridy Code
|
| 23 |
#
|
| 24 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 25 |
# you may not use this file except in compliance with the License.
|
|
|
|
| 51 |
|
| 52 |
###################################################################################
|
| 53 |
|
| 54 |
+
__version__ = "26.2.14"
|
| 55 |
|
| 56 |
print('=' * 70)
|
| 57 |
print('TMIDIX Python module')
|
|
|
|
| 1948 |
|
| 1949 |
###################################################################################
|
| 1950 |
|
| 1951 |
+
def Tegridy_Any_Pickle_File_Writer(Data, input_file_name='TMIDI_Pickle_File', verbose=True):
|
| 1952 |
|
| 1953 |
'''Tegridy Pickle File Writer
|
| 1954 |
|
|
|
|
| 1959 |
|
| 1960 |
Project Los Angeles
|
| 1961 |
Tegridy Code 2021'''
|
| 1962 |
+
|
| 1963 |
+
if verbose:
|
| 1964 |
+
print('Tegridy Pickle File Writer')
|
| 1965 |
|
| 1966 |
full_path_to_output_dataset_to = input_file_name + '.pickle'
|
| 1967 |
|
| 1968 |
if os.path.exists(full_path_to_output_dataset_to):
|
| 1969 |
os.remove(full_path_to_output_dataset_to)
|
| 1970 |
+
if verbose:
|
| 1971 |
+
print('Removing old Dataset...')
|
| 1972 |
else:
|
| 1973 |
+
if verbose:
|
| 1974 |
+
print("Creating new Dataset file...")
|
| 1975 |
|
| 1976 |
with open(full_path_to_output_dataset_to, 'wb') as filehandle:
|
| 1977 |
# store the data as binary data stream
|
| 1978 |
pickle.dump(Data, filehandle, protocol=pickle.HIGHEST_PROTOCOL)
|
| 1979 |
|
| 1980 |
+
if verbose:
|
| 1981 |
+
print('Dataset was saved as:', full_path_to_output_dataset_to)
|
| 1982 |
+
print('Task complete. Enjoy! :)')
|
| 1983 |
|
| 1984 |
###################################################################################
|
| 1985 |
|
|
|
|
| 13319 |
return song_f
|
| 13320 |
|
| 13321 |
###################################################################################
|
| 13322 |
+
|
| 13323 |
+
def add_smooth_expressive_melody_to_enhanced_score_notes(escore_notes,
|
| 13324 |
+
melody_start_chord=0,
|
| 13325 |
+
melody_prime_pitch=60,
|
| 13326 |
+
melody_step=1,
|
| 13327 |
+
melody_channel=3,
|
| 13328 |
+
melody_patch=40,
|
| 13329 |
+
melody_notes_max_duration=255,
|
| 13330 |
+
melody_notes_min_duration=6,
|
| 13331 |
+
melody_last_note_dur=128,
|
| 13332 |
+
suppress_trills=True,
|
| 13333 |
+
melody_smooth_leap=7,
|
| 13334 |
+
melody_clip_max_min_durs=[],
|
| 13335 |
+
melody_max_velocity=120,
|
| 13336 |
+
acc_max_velocity=90,
|
| 13337 |
+
return_melody=False
|
| 13338 |
+
):
|
| 13339 |
+
|
| 13340 |
+
score = copy.deepcopy(escore_notes)
|
| 13341 |
+
adjust_score_velocities(score, acc_max_velocity)
|
| 13342 |
+
cscore = chordify_score([1000, score])
|
| 13343 |
+
|
| 13344 |
+
candidate_indices = [i for i in range(melody_start_chord, len(cscore))
|
| 13345 |
+
if (i - melody_start_chord) % melody_step == 0]
|
| 13346 |
+
|
| 13347 |
+
kept_indices = []
|
| 13348 |
+
|
| 13349 |
+
for i in candidate_indices:
|
| 13350 |
+
|
| 13351 |
+
t = cscore[i][0][1]
|
| 13352 |
+
|
| 13353 |
+
if not kept_indices:
|
| 13354 |
+
kept_indices.append(i)
|
| 13355 |
+
|
| 13356 |
+
else:
|
| 13357 |
+
last_t = cscore[kept_indices[-1]][0][1]
|
| 13358 |
+
|
| 13359 |
+
if t - last_t >= melody_notes_min_duration:
|
| 13360 |
+
kept_indices.append(i)
|
| 13361 |
+
|
| 13362 |
+
melody_pitches = [melody_prime_pitch]
|
| 13363 |
+
|
| 13364 |
+
for idx in kept_indices:
|
| 13365 |
+
chord = cscore[idx]
|
| 13366 |
+
pitches = [e[4] for e in chord if e[3] != 9]
|
| 13367 |
+
|
| 13368 |
+
if not pitches:
|
| 13369 |
+
melody_pitches.append(melody_pitches[-1])
|
| 13370 |
+
continue
|
| 13371 |
+
|
| 13372 |
+
candidates = mult_pitches(pitches)
|
| 13373 |
+
prev = melody_pitches[-1]
|
| 13374 |
+
|
| 13375 |
+
if suppress_trills and len(melody_pitches) >= 2:
|
| 13376 |
+
prev2 = melody_pitches[-2]
|
| 13377 |
+
|
| 13378 |
+
sorted_candidates = sorted(candidates, key=lambda p: abs(p - prev))
|
| 13379 |
+
closest = sorted_candidates[0]
|
| 13380 |
+
|
| 13381 |
+
if prev2 != prev and closest == prev2:
|
| 13382 |
+
|
| 13383 |
+
alt_candidates = [p for p in candidates
|
| 13384 |
+
if p != prev2 and abs(p - prev) <= melody_smooth_leap]
|
| 13385 |
+
|
| 13386 |
+
if alt_candidates:
|
| 13387 |
+
chosen = min(alt_candidates, key=lambda p: abs(p - prev))
|
| 13388 |
+
|
| 13389 |
+
else:
|
| 13390 |
+
chosen = closest
|
| 13391 |
+
|
| 13392 |
+
else:
|
| 13393 |
+
chosen = closest
|
| 13394 |
+
|
| 13395 |
+
else:
|
| 13396 |
+
chosen = min(candidates, key=lambda p: abs(p - prev))
|
| 13397 |
+
|
| 13398 |
+
melody_pitches.append(chosen)
|
| 13399 |
+
|
| 13400 |
+
melody_pitches = melody_pitches[1:]
|
| 13401 |
+
|
| 13402 |
+
mel_f = []
|
| 13403 |
+
|
| 13404 |
+
for j, i in enumerate(kept_indices):
|
| 13405 |
+
|
| 13406 |
+
t = cscore[i][0][1]
|
| 13407 |
+
|
| 13408 |
+
if j < len(kept_indices) - 1:
|
| 13409 |
+
next_t = cscore[kept_indices[j+1]][0][1]
|
| 13410 |
+
dur = min(next_t - t, melody_notes_max_duration)
|
| 13411 |
+
|
| 13412 |
+
else:
|
| 13413 |
+
dur = melody_last_note_dur
|
| 13414 |
+
|
| 13415 |
+
pitch = melody_pitches[j]
|
| 13416 |
+
|
| 13417 |
+
note_num = 60 + (pitch % 24)
|
| 13418 |
+
velocity = 100 + ((pitch % 12) * 2)
|
| 13419 |
+
|
| 13420 |
+
mel_f.append(['note',
|
| 13421 |
+
t,
|
| 13422 |
+
dur,
|
| 13423 |
+
melody_channel,
|
| 13424 |
+
note_num,
|
| 13425 |
+
velocity,
|
| 13426 |
+
melody_patch])
|
| 13427 |
+
|
| 13428 |
+
song_f = []
|
| 13429 |
+
|
| 13430 |
+
for c in cscore:
|
| 13431 |
+
song_f.extend(c)
|
| 13432 |
+
|
| 13433 |
+
if len(melody_clip_max_min_durs) == 2:
|
| 13434 |
+
for e in mel_f:
|
| 13435 |
+
if e[2] >= melody_clip_max_min_durs[0]:
|
| 13436 |
+
e[2] = melody_clip_max_min_durs[1]
|
| 13437 |
+
|
| 13438 |
+
adjust_score_velocities(mel_f, melody_max_velocity)
|
| 13439 |
+
merged_melody = merge_melody_notes(mel_f,
|
| 13440 |
+
max_dur=melody_notes_max_duration,
|
| 13441 |
+
last_dur=melody_last_note_dur)
|
| 13442 |
+
|
| 13443 |
+
song_f = sorted(merged_melody + song_f, key=lambda x: x[1])
|
| 13444 |
+
|
| 13445 |
+
if return_melody:
|
| 13446 |
+
return mel_f
|
| 13447 |
+
|
| 13448 |
+
else:
|
| 13449 |
+
return song_f
|
| 13450 |
+
|
| 13451 |
+
###################################################################################
|
| 13452 |
|
| 13453 |
def list_md5_hash(ints_list):
|
| 13454 |
|