asigalov61 commited on
Commit
e169dd8
·
verified ·
1 Parent(s): 1e13fd1

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +379 -3
TMIDIX.py CHANGED
@@ -51,7 +51,7 @@ r'''############################################################################
51
 
52
  ###################################################################################
53
 
54
- __version__ = "25.8.22"
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.imap_unordered(function, data_list),
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! :)')