asigalov61 commited on
Commit
e63362e
·
verified ·
1 Parent(s): 43cecf5

Upload TMIDIX.py

Browse files
Files changed (1) hide show
  1. TMIDIX.py +1845 -11
TMIDIX.py CHANGED
@@ -14,14 +14,14 @@ r'''############################################################################
14
  #
15
  # Project Los Angeles
16
  #
17
- # Tegridy Code 2021
18
  #
19
  # https://github.com/Tegridy-Code/Project-Los-Angeles
20
  #
21
  #
22
  ###################################################################################
23
  ###################################################################################
24
- # Copyright 2021 Project Los Angeles / Tegridy Code
25
  #
26
  # Licensed under the Apache License, Version 2.0 (the "License");
27
  # you may not use this file except in compliance with the License.
@@ -4690,7 +4690,8 @@ def augment_enhanced_score_notes(enhanced_score_notes,
4690
  pitch_shift=0,
4691
  ceil_timings=False,
4692
  round_timings=False,
4693
- legacy_timings=True
 
4694
  ):
4695
 
4696
  esn = copy.deepcopy(enhanced_score_notes)
@@ -4740,6 +4741,9 @@ def augment_enhanced_score_notes(enhanced_score_notes,
4740
  esn.sort(key=lambda x: x[6])
4741
  esn.sort(key=lambda x: x[4], reverse=True)
4742
  esn.sort(key=lambda x: x[1])
 
 
 
4743
 
4744
  return esn
4745
 
@@ -7097,13 +7101,25 @@ def escore_notes_averages(escore_notes,
7097
  else:
7098
  durs = [e[durs_index] for e in escore_notes if e[chans_index] != 9]
7099
 
 
 
 
 
 
 
7100
  if return_ptcs_and_vels:
7101
  if average_drums:
7102
  ptcs = [e[ptcs_index] for e in escore_notes]
7103
  vels = [e[vels_index] for e in escore_notes]
7104
  else:
7105
  ptcs = [e[ptcs_index] for e in escore_notes if e[chans_index] != 9]
7106
- vels = [e[vels_index] for e in escore_notes if e[chans_index] != 9]
 
 
 
 
 
 
7107
 
7108
  return [sum(times) / len(times), sum(durs) / len(durs), sum(ptcs) / len(ptcs), sum(vels) / len(vels)]
7109
 
@@ -7883,19 +7899,21 @@ def solo_piano_escore_notes(escore_notes,
7883
  chord = []
7884
 
7885
  for cc in c:
7886
- if cc[pitches_index] not in seen:
7887
 
7888
- if cc[channels_index] != 9:
 
 
7889
  cc[channels_index] = 0
7890
  cc[patches_index] = 0
7891
-
7892
  chord.append(cc)
7893
  seen.append(cc[pitches_index])
7894
-
7895
- else:
7896
- if keep_drums:
 
7897
  chord.append(cc)
7898
- seen.append(cc[pitches_index])
7899
 
7900
  sp_escore_notes.append(chord)
7901
 
@@ -9254,6 +9272,1822 @@ def find_highest_density_escore_notes_chunk(escore_notes, max_chunk_time=512):
9254
 
9255
  return chunk_escore
9256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9257
  ###################################################################################
9258
  #
9259
  # This is the end of the TMIDI X Python module
 
14
  #
15
  # Project Los Angeles
16
  #
17
+ # Tegridy Code 2025
18
  #
19
  # https://github.com/Tegridy-Code/Project-Los-Angeles
20
  #
21
  #
22
  ###################################################################################
23
  ###################################################################################
24
+ # Copyright 2025 Project Los Angeles / Tegridy Code
25
  #
26
  # Licensed under the Apache License, Version 2.0 (the "License");
27
  # you may not use this file except in compliance with the License.
 
4690
  pitch_shift=0,
4691
  ceil_timings=False,
4692
  round_timings=False,
4693
+ legacy_timings=True,
4694
+ sort_drums_last=False
4695
  ):
4696
 
4697
  esn = copy.deepcopy(enhanced_score_notes)
 
4741
  esn.sort(key=lambda x: x[6])
4742
  esn.sort(key=lambda x: x[4], reverse=True)
4743
  esn.sort(key=lambda x: x[1])
4744
+
4745
+ if sort_drums_last:
4746
+ esn.sort(key=lambda x: (x[1], -x[4], x[6]) if x[6] != 128 else (x[1], x[6], -x[4]))
4747
 
4748
  return esn
4749
 
 
7101
  else:
7102
  durs = [e[durs_index] for e in escore_notes if e[chans_index] != 9]
7103
 
7104
+ if len(times) == 0:
7105
+ times = [0]
7106
+
7107
+ if len(durs) == 0:
7108
+ durs = [0]
7109
+
7110
  if return_ptcs_and_vels:
7111
  if average_drums:
7112
  ptcs = [e[ptcs_index] for e in escore_notes]
7113
  vels = [e[vels_index] for e in escore_notes]
7114
  else:
7115
  ptcs = [e[ptcs_index] for e in escore_notes if e[chans_index] != 9]
7116
+ vels = [e[vels_index] for e in escore_notes if e[chans_index] != 9]
7117
+
7118
+ if len(ptcs) == 0:
7119
+ ptcs = [0]
7120
+
7121
+ if len(vels) == 0:
7122
+ vels = [0]
7123
 
7124
  return [sum(times) / len(times), sum(durs) / len(durs), sum(ptcs) / len(ptcs), sum(vels) / len(vels)]
7125
 
 
7899
  chord = []
7900
 
7901
  for cc in c:
 
7902
 
7903
+ if cc[channels_index] != 9:
7904
+ if cc[pitches_index] not in seen:
7905
+
7906
  cc[channels_index] = 0
7907
  cc[patches_index] = 0
7908
+
7909
  chord.append(cc)
7910
  seen.append(cc[pitches_index])
7911
+
7912
+ else:
7913
+ if keep_drums:
7914
+ if cc[pitches_index]+128 not in seen:
7915
  chord.append(cc)
7916
+ seen.append(cc[pitches_index]+128)
7917
 
7918
  sp_escore_notes.append(chord)
7919
 
 
9272
 
9273
  return chunk_escore
9274
 
9275
+ ###################################################################################
9276
+
9277
+ def advanced_add_drums_to_escore_notes(escore_notes,
9278
+ main_beat_min_dtime=5,
9279
+ main_beat_dtime_thres=1,
9280
+ drums_durations_value=2,
9281
+ drums_pitches_velocities=[(36, 100),
9282
+ (38, 100),
9283
+ (41, 125)],
9284
+ recalculate_score_timings=True,
9285
+ intro_drums_count=4,
9286
+ intro_drums_time_k=4,
9287
+ intro_drums_pitch_velocity=[37, 110]
9288
+ ):
9289
+
9290
+ #===========================================================
9291
+
9292
+ new_dscore = delta_score_notes(escore_notes)
9293
+
9294
+ times = [d[1] for d in new_dscore if d[1] != 0]
9295
+
9296
+ time = [c[0] for c in Counter(times).most_common() if c[0] >= main_beat_min_dtime][0]
9297
+
9298
+ #===========================================================
9299
+
9300
+ if intro_drums_count > 0:
9301
+
9302
+ drums_score = []
9303
+
9304
+ for i in range(intro_drums_count):
9305
+
9306
+ if i == 0:
9307
+ dtime = 0
9308
+
9309
+ else:
9310
+ dtime = time
9311
+
9312
+ drums_score.append(['note',
9313
+ dtime * intro_drums_time_k,
9314
+ drums_durations_value,
9315
+ 9,
9316
+ intro_drums_pitch_velocity[0],
9317
+ intro_drums_pitch_velocity[1],
9318
+ 128]
9319
+ )
9320
+
9321
+ new_dscore[0][1] = time * intro_drums_time_k
9322
+
9323
+ new_dscore = drums_score + new_dscore
9324
+
9325
+ #===========================================================
9326
+
9327
+ for e in new_dscore:
9328
+
9329
+ if abs(e[1] - time) == main_beat_dtime_thres:
9330
+ e[1] = time
9331
+
9332
+ if recalculate_score_timings:
9333
+
9334
+ if e[1] % time != 0 and e[1] > time:
9335
+ if e[1] % time < time // 2:
9336
+ e[1] -= e[1] % time
9337
+
9338
+ else:
9339
+ e[1] += time - (e[1] % time)
9340
+
9341
+ #===========================================================
9342
+
9343
+ drums_score = []
9344
+
9345
+ dtime = 0
9346
+
9347
+ idx = 0
9348
+
9349
+ for i, e in enumerate(new_dscore):
9350
+
9351
+ drums_score.append(e)
9352
+
9353
+ dtime += e[1]
9354
+
9355
+ if e[1] != 0:
9356
+ idx += 1
9357
+
9358
+ if i >= intro_drums_count:
9359
+
9360
+ if (e[1] % time == 0 and e[1] != 0) or i == 0:
9361
+
9362
+ if idx % 2 == 0 and e[1] != 0:
9363
+ drums_score.append(['note',
9364
+ 0,
9365
+ drums_durations_value,
9366
+ 9,
9367
+ drums_pitches_velocities[0][0],
9368
+ drums_pitches_velocities[0][1],
9369
+ 128]
9370
+ )
9371
+
9372
+ if idx % 2 != 0 and e[1] != 0:
9373
+ drums_score.append(['note',
9374
+ 0,
9375
+ drums_durations_value,
9376
+ 9,
9377
+ drums_pitches_velocities[1][0],
9378
+ drums_pitches_velocities[1][1],
9379
+ 128]
9380
+ )
9381
+
9382
+ if idx % 4 == 0 and e[1] != 0:
9383
+ drums_score.append(['note',
9384
+ 0,
9385
+ drums_durations_value,
9386
+ 9,
9387
+ drums_pitches_velocities[2][0],
9388
+ drums_pitches_velocities[2][1],
9389
+ 128]
9390
+ )
9391
+
9392
+ #===========================================================
9393
+
9394
+ return delta_score_to_abs_score(drums_score)
9395
+
9396
+ ###################################################################################
9397
+
9398
+ MIDI_TEXT_EVENTS = ['text_event',
9399
+ 'copyright_text_event',
9400
+ 'track_name',
9401
+ 'instrument_name',
9402
+ 'lyric',
9403
+ 'marker',
9404
+ 'cue_point',
9405
+ 'text_event_08',
9406
+ 'text_event_09',
9407
+ 'text_event_0a',
9408
+ 'text_event_0b',
9409
+ 'text_event_0c',
9410
+ 'text_event_0d',
9411
+ 'text_event_0e',
9412
+ 'text_event_0f'
9413
+ ]
9414
+
9415
+ ###################################################################################
9416
+
9417
+ import hashlib
9418
+ import re
9419
+
9420
+ ###################################################################################
9421
+
9422
+ def get_md5_hash(data):
9423
+ return hashlib.md5(data).hexdigest()
9424
+
9425
+ ###################################################################################
9426
+
9427
+ def is_valid_md5_hash(string):
9428
+ return bool(re.match(r'^[a-fA-F0-9]{32}$', string))
9429
+
9430
+ ###################################################################################
9431
+
9432
+ def clean_string(original_string,
9433
+ regex=r'[^a-zA-Z0-9 ]',
9434
+ remove_duplicate_spaces=True,
9435
+ title=False
9436
+ ):
9437
+
9438
+ cstr1 = re.sub(regex, '', original_string)
9439
+
9440
+ if title:
9441
+ cstr1 = cstr1.title()
9442
+
9443
+ if remove_duplicate_spaces:
9444
+ return re.sub(r'[ ]+', ' ', cstr1).strip()
9445
+
9446
+ else:
9447
+ return cstr1
9448
+
9449
+ ###################################################################################
9450
+
9451
+ def encode_to_ord(text, chars_range=[], sub_char='', chars_shift=0):
9452
+
9453
+ if not chars_range:
9454
+ chars_range = [32] + list(range(65, 91)) + list(range(97, 123))
9455
+
9456
+ if sub_char:
9457
+ chars_range.append(ord(sub_char))
9458
+
9459
+ chars_range = sorted(set(chars_range))
9460
+
9461
+ encoded = []
9462
+
9463
+ for char in text:
9464
+ if ord(char) in chars_range:
9465
+ encoded.append(chars_range.index(ord(char)) + chars_shift)
9466
+
9467
+ else:
9468
+ if sub_char:
9469
+ encoded.append(chars_range.index(ord(sub_char)) + chars_shift)
9470
+
9471
+
9472
+ return [encoded, chars_range]
9473
+
9474
+ ###################################################################################
9475
+
9476
+ def decode_from_ord(ord_list, chars_range=[], sub_char='', chars_shift=0):
9477
+
9478
+ if not chars_range:
9479
+ chars_range = [32] + list(range(65, 91)) + list(range(97, 123))
9480
+
9481
+ if sub_char:
9482
+ chars_range.append(ord(sub_char))
9483
+
9484
+ chars_range = sorted(set(chars_range))
9485
+
9486
+ return ''.join(chr(chars_range[num-chars_shift]) if 0 <= num-chars_shift < len(chars_range) else sub_char for num in ord_list)
9487
+
9488
+ ###################################################################################
9489
+
9490
+ def lists_similarity(list1, list2, by_elements=True, by_sum=True):
9491
+
9492
+ if len(list1) != len(list2):
9493
+ return -1
9494
+
9495
+ element_ratios = []
9496
+ total_counts1 = sum(list1)
9497
+ total_counts2 = sum(list2)
9498
+
9499
+ for a, b in zip(list1, list2):
9500
+ if a == 0 and b == 0:
9501
+ element_ratios.append(1)
9502
+ elif a == 0 or b == 0:
9503
+ element_ratios.append(0)
9504
+ else:
9505
+ element_ratios.append(min(a, b) / max(a, b))
9506
+
9507
+ average_element_ratio = sum(element_ratios) / len(element_ratios)
9508
+
9509
+ total_counts_ratio = min(total_counts1, total_counts2) / max(total_counts1, total_counts2)
9510
+
9511
+ if by_elements and by_sum:
9512
+ return (average_element_ratio + total_counts_ratio) / 2
9513
+
9514
+ elif by_elements and not by_sum:
9515
+ return average_element_ratio
9516
+
9517
+ elif not by_elements and by_sum:
9518
+ return total_counts_ratio
9519
+
9520
+ else:
9521
+ return -1
9522
+
9523
+ ###################################################################################
9524
+
9525
+ def find_indexes(lst, value, mode='equal', dual_mode=True):
9526
+
9527
+ indexes = []
9528
+
9529
+ if mode == 'equal' or dual_mode:
9530
+ indexes.extend([index for index, elem in enumerate(lst) if elem == value])
9531
+
9532
+ if mode == 'smaller':
9533
+ indexes.extend([index for index, elem in enumerate(lst) if elem < value])
9534
+
9535
+ if mode == 'larger':
9536
+ indexes.extend([index for index, elem in enumerate(lst) if elem > value])
9537
+
9538
+ return sorted(set(indexes))
9539
+
9540
+ ###################################################################################
9541
+
9542
+ NUMERALS = ["one", "two", "three", "four",
9543
+ "five", "six", "seven", "eight",
9544
+ "nine", "ten", "eleven", "twelve",
9545
+ "thirteen", "fourteen", "fifteen", "sixteen"
9546
+ ]
9547
+
9548
+ SEMITONES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
9549
+
9550
+ BASIC_SCALES = ['Major', 'Minor']
9551
+
9552
+ ###################################################################################
9553
+
9554
+ def alpha_str(string):
9555
+ astr = re.sub(r'[^a-zA-Z ()0-9]', '', string).strip()
9556
+ return re.sub(r'\s+', ' ', astr).strip()
9557
+
9558
+ ###################################################################################
9559
+
9560
+ def escore_notes_to_text_description(escore_notes,
9561
+ song_name='',
9562
+ artist_name='',
9563
+ timings_divider=16,
9564
+ ):
9565
+
9566
+ #==============================================================================
9567
+
9568
+ song_time_min = (escore_notes[-1][1] * timings_divider) / 1000 / 60
9569
+
9570
+ if song_time_min < 1.5:
9571
+ song_length = 'short'
9572
+
9573
+ elif 1.5 <= song_time_min < 2.5:
9574
+ song_length = 'average'
9575
+
9576
+ elif song_time_min >= 2.5:
9577
+ song_length = 'long'
9578
+
9579
+ #==============================================================================
9580
+
9581
+ escore_times = [e[1] for e in escore_notes if e[3] != 9]
9582
+
9583
+ comp_type = ''
9584
+
9585
+ if len(escore_times) > 0:
9586
+ if len(escore_times) == len(set(escore_times)):
9587
+ comp_type = 'monophonic melody'
9588
+ ctype = 'melody'
9589
+
9590
+ elif len(escore_times) >= len(set(escore_times)) and 1 in Counter(escore_times).values():
9591
+ comp_type = 'melody and accompaniment'
9592
+ ctype = 'song'
9593
+
9594
+ elif len(escore_times) >= len(set(escore_times)) and 1 not in Counter(escore_times).values():
9595
+ comp_type = 'accompaniment'
9596
+ ctype = 'song'
9597
+
9598
+ else:
9599
+ comp_type = 'drum track'
9600
+ ctype = 'drum track'
9601
+
9602
+ #==============================================================================
9603
+
9604
+ all_patches = [e[6] for e in escore_notes]
9605
+
9606
+ patches = ordered_set(all_patches)
9607
+
9608
+ instruments = [alpha_str(Number2patch[p]) for p in patches if p < 128]
9609
+
9610
+ if instruments:
9611
+
9612
+ nd_patches_counts = Counter([p for p in all_patches if p < 128]).most_common()
9613
+
9614
+ dominant_instrument = alpha_str(Number2patch[nd_patches_counts[0][0]])
9615
+
9616
+ if 128 in patches:
9617
+ drums_present = True
9618
+
9619
+ drums_pitches = [e[4] for e in escore_notes if e[3] == 9]
9620
+
9621
+ most_common_drums = [alpha_str(Notenum2percussion[p[0]]) for p in Counter(drums_pitches).most_common(3) if p[0] in Notenum2percussion]
9622
+
9623
+ else:
9624
+ drums_present = False
9625
+
9626
+ #==============================================================================
9627
+
9628
+ pitches = [e[4] for e in escore_notes if e[3] != 9]
9629
+
9630
+ key = ''
9631
+
9632
+ if pitches:
9633
+ key = SEMITONES[statistics.mode(pitches) % 12]
9634
+
9635
+ #==============================================================================
9636
+
9637
+ scale = ''
9638
+ mood = ''
9639
+
9640
+ if pitches:
9641
+
9642
+ result = escore_notes_scale(escore_notes)
9643
+
9644
+ scale = result[0]
9645
+ mood = result[1].split(' ')[0].lower()
9646
+
9647
+ #==============================================================================
9648
+
9649
+ if pitches:
9650
+
9651
+ escore_averages = escore_notes_averages(escore_notes, return_ptcs_and_vels=True)
9652
+
9653
+ if escore_averages[0] < (128 / timings_divider):
9654
+ rythm = 'fast'
9655
+
9656
+ elif (128 / timings_divider) <= escore_averages[0] <= (192 / timings_divider):
9657
+ rythm = 'average'
9658
+
9659
+ elif escore_averages[0] > (192 / timings_divider):
9660
+ rythm = 'slow'
9661
+
9662
+ if escore_averages[1] < (256 / timings_divider):
9663
+ tempo = 'fast'
9664
+
9665
+ elif (256 / timings_divider) <= escore_averages[1] <= (384 / timings_divider):
9666
+ tempo = 'average'
9667
+
9668
+ elif escore_averages[1] > (384 / timings_divider):
9669
+ tempo = 'slow'
9670
+
9671
+ if escore_averages[2] < 50:
9672
+ tone = 'bass'
9673
+
9674
+ elif 50 <= escore_averages[2] <= 70:
9675
+ tone = 'midrange'
9676
+
9677
+ elif escore_averages[2] > 70:
9678
+ tone = 'treble'
9679
+
9680
+ if escore_averages[3] < 64:
9681
+ dynamics = 'quiet'
9682
+
9683
+ elif 64 <= escore_averages[3] <= 96:
9684
+ dynamics = 'average'
9685
+
9686
+ elif escore_averages[3] > 96:
9687
+ dynamics = 'loud'
9688
+
9689
+ #==============================================================================
9690
+
9691
+ mono_melodies = escore_notes_monoponic_melodies([e for e in escore_notes if e[6] < 88])
9692
+
9693
+ lead_melodies = []
9694
+ base_melodies = []
9695
+
9696
+ if mono_melodies:
9697
+
9698
+ for mel in mono_melodies:
9699
+
9700
+ escore_avgs = escore_notes_pitches_range(escore_notes, range_patch = mel[0])
9701
+
9702
+ if mel[0] in LEAD_INSTRUMENTS and escore_avgs[3] > 60:
9703
+ lead_melodies.append([Number2patch[mel[0]], mel[1]])
9704
+
9705
+ elif mel[0] in BASE_INSTRUMENTS and escore_avgs[3] <= 60:
9706
+ base_melodies.append([Number2patch[mel[0]], mel[1]])
9707
+
9708
+ if lead_melodies:
9709
+ lead_melodies.sort(key=lambda x: x[1], reverse=True)
9710
+
9711
+ if base_melodies:
9712
+ base_melodies.sort(key=lambda x: x[1], reverse=True)
9713
+
9714
+ #==============================================================================
9715
+
9716
+ description = ''
9717
+
9718
+ if song_name != '':
9719
+ description = 'The song "' + song_name + '"'
9720
+
9721
+ if artist_name != '':
9722
+ description += ' by ' + artist_name
9723
+
9724
+ if song_name != '' or artist_name != '':
9725
+ description += '.'
9726
+ description += '\n'
9727
+
9728
+ description += 'The song is '
9729
+
9730
+ if song_length != 'average':
9731
+ description += 'a ' + song_length
9732
+
9733
+ else:
9734
+ description += 'an ' + song_length
9735
+
9736
+ description += ' duration '
9737
+
9738
+ description += comp_type + ' composition'
9739
+
9740
+ if comp_type != 'drum track':
9741
+
9742
+ if drums_present:
9743
+ description += ' with drums'
9744
+
9745
+ else:
9746
+ description += ' without drums'
9747
+
9748
+ if key and scale:
9749
+ description += ' in ' + key + ' ' + scale
9750
+
9751
+ description += '.'
9752
+
9753
+ description += '\n'
9754
+
9755
+ if pitches:
9756
+
9757
+ if comp_type not in ['monophonic melody', 'drum track']:
9758
+
9759
+ description += 'This ' + mood + ' song has '
9760
+
9761
+ elif comp_type == 'monophonic melody':
9762
+
9763
+ description += 'This ' + mood + ' melody has '
9764
+
9765
+ else:
9766
+ description += 'TThis drum track has '
9767
+
9768
+ description += rythm + ' rythm, '
9769
+ description += tempo + ' tempo, '
9770
+ description += tone + ' tone and '
9771
+ description += dynamics + ' dynamics.'
9772
+
9773
+ description += '\n'
9774
+
9775
+ if instruments:
9776
+
9777
+ if comp_type not in ['monophonic melody', 'drum track']:
9778
+
9779
+ description += 'The song '
9780
+
9781
+ if len(instruments) > 1:
9782
+
9783
+ description += 'features ' + NUMERALS[max(0, min(15, len(instruments)-1))] + ' instruments: '
9784
+ description += ', '.join(instruments[:-1]) + ' and ' + instruments[-1] + '.'
9785
+
9786
+ else:
9787
+ description += 'features one instrument: ' + instruments[0] + '.'
9788
+
9789
+
9790
+ description += '\n'
9791
+
9792
+ if instruments[0] != dominant_instrument:
9793
+ description += 'The song opens with ' + instruments[0]
9794
+
9795
+ description += ' and primarily performed on ' + dominant_instrument + '.'
9796
+
9797
+ else:
9798
+ description += 'The song opens with and performed on ' + instruments[0] + '.'
9799
+
9800
+ description += '\n'
9801
+
9802
+ if lead_melodies or base_melodies:
9803
+
9804
+ tm_count = len(lead_melodies + base_melodies)
9805
+
9806
+ if tm_count == 1:
9807
+
9808
+ if lead_melodies:
9809
+ description += 'The song has one distinct lead melody played on ' + lead_melodies[0][0] + '.'
9810
+
9811
+ else:
9812
+ description += 'The song has one distinct base melody played on ' + base_melodies[0][0] + '.'
9813
+
9814
+ description += '\n'
9815
+
9816
+ else:
9817
+
9818
+ if lead_melodies and not base_melodies:
9819
+
9820
+ if len(lead_melodies) == 1:
9821
+ mword = 'melody'
9822
+
9823
+ else:
9824
+ mword = 'melodies'
9825
+
9826
+ description += 'The song has ' + NUMERALS[len(lead_melodies)-1] + ' distinct lead ' + mword + ' played on '
9827
+
9828
+ if len(lead_melodies) > 1:
9829
+ description += ', '.join([l[0] for l in lead_melodies[:-1]]) + ' and ' + lead_melodies[-1][0] + '.'
9830
+
9831
+ else:
9832
+ description += lead_melodies[0][0] + '.'
9833
+
9834
+ description += '\n'
9835
+
9836
+ elif base_melodies and not lead_melodies:
9837
+
9838
+ if len(base_melodies) == 1:
9839
+ mword = 'melody'
9840
+
9841
+ else:
9842
+ mword = 'melodies'
9843
+
9844
+ description += 'The song has ' + NUMERALS[len(base_melodies)-1] + ' distinct base ' + mword + ' played on '
9845
+
9846
+ if len(base_melodies) > 1:
9847
+ description += ', '.join([b[0] for b in base_melodies[:-1]]) + ' and ' + base_melodies[-1][0] + '.'
9848
+
9849
+ else:
9850
+ description += base_melodies[0][0] + '.'
9851
+
9852
+ description += '\n'
9853
+
9854
+ elif lead_melodies and base_melodies:
9855
+
9856
+ if len(lead_melodies) == 1:
9857
+ lmword = 'melody'
9858
+
9859
+ else:
9860
+ lmword = 'melodies'
9861
+
9862
+ description += 'The song has ' + NUMERALS[len(lead_melodies)-1] + ' distinct lead ' + lmword + ' played on '
9863
+
9864
+ if len(lead_melodies) > 1:
9865
+ description += ', '.join([l[0] for l in lead_melodies[:-1]]) + ' and ' + lead_melodies[-1][0] + '.'
9866
+
9867
+ else:
9868
+ description += lead_melodies[0][0] + '.'
9869
+
9870
+ if len(base_melodies) == 1:
9871
+ bmword = 'melody'
9872
+
9873
+ else:
9874
+ bmword = 'melodies'
9875
+
9876
+ description += ' And ' + NUMERALS[len(base_melodies)-1] + ' distinct base ' + bmword + ' played on '
9877
+
9878
+ if len(base_melodies) > 1:
9879
+ description += ', '.join([b[0] for b in base_melodies[:-1]]) + ' and ' + base_melodies[-1][0] + '.'
9880
+
9881
+ else:
9882
+ description += base_melodies[0][0] + '.'
9883
+
9884
+ description += '\n'
9885
+
9886
+ if drums_present and most_common_drums:
9887
+
9888
+ if len(most_common_drums) > 1:
9889
+ description += 'The drum track has predominant '
9890
+ description += ', '.join(most_common_drums[:-1]) + ' and ' + most_common_drums[-1] + '.'
9891
+
9892
+ else:
9893
+ description += 'The drum track is a solo '
9894
+ description += most_common_drums[0] + '.'
9895
+
9896
+ description += '\n'
9897
+
9898
+ #==============================================================================
9899
+
9900
+ return description
9901
+
9902
+ ###################################################################################
9903
+
9904
+ #==================================================================================
9905
+ #
9906
+ # Below constants code is a courtesy of MidiTok
9907
+ #
9908
+ # Retrieved on 12/29/2024
9909
+ #
9910
+ # https://github.com/Natooz/MidiTok/blob/main/src/miditok/constants.py
9911
+ #
9912
+ #==================================================================================
9913
+
9914
+ MIDI_FILES_EXTENSIONS = [".mid", ".midi", ".kar", ".MID", ".MIDI", ".KAR"]
9915
+
9916
+ # The recommended pitches for piano in the GM2 specs are from 21 to 108
9917
+ PIANO_PITCH_RANGE = range(21, 109)
9918
+
9919
+ # Chord params
9920
+ # "chord_unknown" specifies the range of number of notes that can form "unknown" chords
9921
+ # (that do not fit in "chord_maps") to add in tokens.
9922
+ # Known chord maps, with 0 as root note
9923
+ BASIC_CHORDS_MAP = {
9924
+ "min": (0, 3, 7),
9925
+ "maj": (0, 4, 7),
9926
+ "dim": (0, 3, 6),
9927
+ "aug": (0, 4, 8),
9928
+ "sus2": (0, 2, 7),
9929
+ "sus4": (0, 5, 7),
9930
+ "7dom": (0, 4, 7, 10),
9931
+ "7min": (0, 3, 7, 10),
9932
+ "7maj": (0, 4, 7, 11),
9933
+ "7halfdim": (0, 3, 6, 10),
9934
+ "7dim": (0, 3, 6, 9),
9935
+ "7aug": (0, 4, 8, 11),
9936
+ "9maj": (0, 4, 7, 10, 14),
9937
+ "9min": (0, 4, 7, 10, 13),
9938
+ }
9939
+
9940
+ # Drums
9941
+ # Recommended range from the GM2 specs
9942
+ DRUMS_PITCH_RANGE = range(27, 90)
9943
+
9944
+ # Used with chords
9945
+ PITCH_CLASSES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
9946
+
9947
+ # http://newt.phys.unsw.edu.au/jw/notes.html
9948
+ # https://www.midi.org/specifications
9949
+
9950
+ # index i = program i+1 in the GM2 specs (7. Appendix A)
9951
+ # index i = program i as retrieved by packages
9952
+ MIDI_INSTRUMENTS = [
9953
+ # Piano
9954
+ {"name": "Acoustic Grand Piano", "pitch_range": range(21, 109)},
9955
+ {"name": "Bright Acoustic Piano", "pitch_range": range(21, 109)},
9956
+ {"name": "Electric Grand Piano", "pitch_range": range(21, 109)},
9957
+ {"name": "Honky-tonk Piano", "pitch_range": range(21, 109)},
9958
+ {"name": "Electric Piano 1", "pitch_range": range(28, 104)},
9959
+ {"name": "Electric Piano 2", "pitch_range": range(28, 104)},
9960
+ {"name": "Harpsichord", "pitch_range": range(41, 90)},
9961
+ {"name": "Clavi", "pitch_range": range(36, 97)},
9962
+ # Chromatic Percussion
9963
+ {"name": "Celesta", "pitch_range": range(60, 109)},
9964
+ {"name": "Glockenspiel", "pitch_range": range(72, 109)},
9965
+ {"name": "Music Box", "pitch_range": range(60, 85)},
9966
+ {"name": "Vibraphone", "pitch_range": range(53, 90)},
9967
+ {"name": "Marimba", "pitch_range": range(48, 85)},
9968
+ {"name": "Xylophone", "pitch_range": range(65, 97)},
9969
+ {"name": "Tubular Bells", "pitch_range": range(60, 78)},
9970
+ {"name": "Dulcimer", "pitch_range": range(60, 85)},
9971
+ # Organs
9972
+ {"name": "Drawbar Organ", "pitch_range": range(36, 97)},
9973
+ {"name": "Percussive Organ", "pitch_range": range(36, 97)},
9974
+ {"name": "Rock Organ", "pitch_range": range(36, 97)},
9975
+ {"name": "Church Organ", "pitch_range": range(21, 109)},
9976
+ {"name": "Reed Organ", "pitch_range": range(36, 97)},
9977
+ {"name": "Accordion", "pitch_range": range(53, 90)},
9978
+ {"name": "Harmonica", "pitch_range": range(60, 85)},
9979
+ {"name": "Tango Accordion", "pitch_range": range(53, 90)},
9980
+ # Guitars
9981
+ {"name": "Acoustic Guitar (nylon)", "pitch_range": range(40, 85)},
9982
+ {"name": "Acoustic Guitar (steel)", "pitch_range": range(40, 85)},
9983
+ {"name": "Electric Guitar (jazz)", "pitch_range": range(40, 87)},
9984
+ {"name": "Electric Guitar (clean)", "pitch_range": range(40, 87)},
9985
+ {"name": "Electric Guitar (muted)", "pitch_range": range(40, 87)},
9986
+ {"name": "Overdriven Guitar", "pitch_range": range(40, 87)},
9987
+ {"name": "Distortion Guitar", "pitch_range": range(40, 87)},
9988
+ {"name": "Guitar Harmonics", "pitch_range": range(40, 87)},
9989
+ # Bass
9990
+ {"name": "Acoustic Bass", "pitch_range": range(28, 56)},
9991
+ {"name": "Electric Bass (finger)", "pitch_range": range(28, 56)},
9992
+ {"name": "Electric Bass (pick)", "pitch_range": range(28, 56)},
9993
+ {"name": "Fretless Bass", "pitch_range": range(28, 56)},
9994
+ {"name": "Slap Bass 1", "pitch_range": range(28, 56)},
9995
+ {"name": "Slap Bass 2", "pitch_range": range(28, 56)},
9996
+ {"name": "Synth Bass 1", "pitch_range": range(28, 56)},
9997
+ {"name": "Synth Bass 2", "pitch_range": range(28, 56)},
9998
+ # Strings & Orchestral instruments
9999
+ {"name": "Violin", "pitch_range": range(55, 94)},
10000
+ {"name": "Viola", "pitch_range": range(48, 85)},
10001
+ {"name": "Cello", "pitch_range": range(36, 73)},
10002
+ {"name": "Contrabass", "pitch_range": range(28, 56)},
10003
+ {"name": "Tremolo Strings", "pitch_range": range(28, 94)},
10004
+ {"name": "Pizzicato Strings", "pitch_range": range(28, 94)},
10005
+ {"name": "Orchestral Harp", "pitch_range": range(23, 104)},
10006
+ {"name": "Timpani", "pitch_range": range(36, 58)},
10007
+ # Ensembles
10008
+ {"name": "String Ensembles 1", "pitch_range": range(28, 97)},
10009
+ {"name": "String Ensembles 2", "pitch_range": range(28, 97)},
10010
+ {"name": "SynthStrings 1", "pitch_range": range(36, 97)},
10011
+ {"name": "SynthStrings 2", "pitch_range": range(36, 97)},
10012
+ {"name": "Choir Aahs", "pitch_range": range(48, 80)},
10013
+ {"name": "Voice Oohs", "pitch_range": range(48, 80)},
10014
+ {"name": "Synth Voice", "pitch_range": range(48, 85)},
10015
+ {"name": "Orchestra Hit", "pitch_range": range(48, 73)},
10016
+ # Brass
10017
+ {"name": "Trumpet", "pitch_range": range(58, 95)},
10018
+ {"name": "Trombone", "pitch_range": range(34, 76)},
10019
+ {"name": "Tuba", "pitch_range": range(29, 56)},
10020
+ {"name": "Muted Trumpet", "pitch_range": range(58, 83)},
10021
+ {"name": "French Horn", "pitch_range": range(41, 78)},
10022
+ {"name": "Brass Section", "pitch_range": range(36, 97)},
10023
+ {"name": "Synth Brass 1", "pitch_range": range(36, 97)},
10024
+ {"name": "Synth Brass 2", "pitch_range": range(36, 97)},
10025
+ # Reed
10026
+ {"name": "Soprano Sax", "pitch_range": range(54, 88)},
10027
+ {"name": "Alto Sax", "pitch_range": range(49, 81)},
10028
+ {"name": "Tenor Sax", "pitch_range": range(42, 76)},
10029
+ {"name": "Baritone Sax", "pitch_range": range(37, 69)},
10030
+ {"name": "Oboe", "pitch_range": range(58, 92)},
10031
+ {"name": "English Horn", "pitch_range": range(52, 82)},
10032
+ {"name": "Bassoon", "pitch_range": range(34, 73)},
10033
+ {"name": "Clarinet", "pitch_range": range(50, 92)},
10034
+ # Pipe
10035
+ {"name": "Piccolo", "pitch_range": range(74, 109)},
10036
+ {"name": "Flute", "pitch_range": range(60, 97)},
10037
+ {"name": "Recorder", "pitch_range": range(60, 97)},
10038
+ {"name": "Pan Flute", "pitch_range": range(60, 97)},
10039
+ {"name": "Blown Bottle", "pitch_range": range(60, 97)},
10040
+ {"name": "Shakuhachi", "pitch_range": range(55, 85)},
10041
+ {"name": "Whistle", "pitch_range": range(60, 97)},
10042
+ {"name": "Ocarina", "pitch_range": range(60, 85)},
10043
+ # Synth Lead
10044
+ {"name": "Lead 1 (square)", "pitch_range": range(21, 109)},
10045
+ {"name": "Lead 2 (sawtooth)", "pitch_range": range(21, 109)},
10046
+ {"name": "Lead 3 (calliope)", "pitch_range": range(36, 97)},
10047
+ {"name": "Lead 4 (chiff)", "pitch_range": range(36, 97)},
10048
+ {"name": "Lead 5 (charang)", "pitch_range": range(36, 97)},
10049
+ {"name": "Lead 6 (voice)", "pitch_range": range(36, 97)},
10050
+ {"name": "Lead 7 (fifths)", "pitch_range": range(36, 97)},
10051
+ {"name": "Lead 8 (bass + lead)", "pitch_range": range(21, 109)},
10052
+ # Synth Pad
10053
+ {"name": "Pad 1 (new age)", "pitch_range": range(36, 97)},
10054
+ {"name": "Pad 2 (warm)", "pitch_range": range(36, 97)},
10055
+ {"name": "Pad 3 (polysynth)", "pitch_range": range(36, 97)},
10056
+ {"name": "Pad 4 (choir)", "pitch_range": range(36, 97)},
10057
+ {"name": "Pad 5 (bowed)", "pitch_range": range(36, 97)},
10058
+ {"name": "Pad 6 (metallic)", "pitch_range": range(36, 97)},
10059
+ {"name": "Pad 7 (halo)", "pitch_range": range(36, 97)},
10060
+ {"name": "Pad 8 (sweep)", "pitch_range": range(36, 97)},
10061
+ # Synth SFX
10062
+ {"name": "FX 1 (rain)", "pitch_range": range(36, 97)},
10063
+ {"name": "FX 2 (soundtrack)", "pitch_range": range(36, 97)},
10064
+ {"name": "FX 3 (crystal)", "pitch_range": range(36, 97)},
10065
+ {"name": "FX 4 (atmosphere)", "pitch_range": range(36, 97)},
10066
+ {"name": "FX 5 (brightness)", "pitch_range": range(36, 97)},
10067
+ {"name": "FX 6 (goblins)", "pitch_range": range(36, 97)},
10068
+ {"name": "FX 7 (echoes)", "pitch_range": range(36, 97)},
10069
+ {"name": "FX 8 (sci-fi)", "pitch_range": range(36, 97)},
10070
+ # Ethnic Misc.
10071
+ {"name": "Sitar", "pitch_range": range(48, 78)},
10072
+ {"name": "Banjo", "pitch_range": range(48, 85)},
10073
+ {"name": "Shamisen", "pitch_range": range(50, 80)},
10074
+ {"name": "Koto", "pitch_range": range(55, 85)},
10075
+ {"name": "Kalimba", "pitch_range": range(48, 80)},
10076
+ {"name": "Bag pipe", "pitch_range": range(36, 78)},
10077
+ {"name": "Fiddle", "pitch_range": range(55, 97)},
10078
+ {"name": "Shanai", "pitch_range": range(48, 73)},
10079
+ # Percussive
10080
+ {"name": "Tinkle Bell", "pitch_range": range(72, 85)},
10081
+ {"name": "Agogo", "pitch_range": range(60, 73)},
10082
+ {"name": "Steel Drums", "pitch_range": range(52, 77)},
10083
+ {"name": "Woodblock", "pitch_range": range(128)},
10084
+ {"name": "Taiko Drum", "pitch_range": range(128)},
10085
+ {"name": "Melodic Tom", "pitch_range": range(128)},
10086
+ {"name": "Synth Drum", "pitch_range": range(128)},
10087
+ {"name": "Reverse Cymbal", "pitch_range": range(128)},
10088
+ # SFX
10089
+ {"name": "Guitar Fret Noise, Guitar Cutting Noise", "pitch_range": range(128)},
10090
+ {"name": "Breath Noise, Flute Key Click", "pitch_range": range(128)},
10091
+ {
10092
+ "name": "Seashore, Rain, Thunder, Wind, Stream, Bubbles",
10093
+ "pitch_range": range(128),
10094
+ },
10095
+ {"name": "Bird Tweet, Dog, Horse Gallop", "pitch_range": range(128)},
10096
+ {
10097
+ "name": "Telephone Ring, Door Creaking, Door, Scratch, Wind Chime",
10098
+ "pitch_range": range(128),
10099
+ },
10100
+ {"name": "Helicopter, Car Sounds", "pitch_range": range(128)},
10101
+ {
10102
+ "name": "Applause, Laughing, Screaming, Punch, Heart Beat, Footstep",
10103
+ "pitch_range": range(128),
10104
+ },
10105
+ {"name": "Gunshot, Machine Gun, Lasergun, Explosion", "pitch_range": range(128)},
10106
+ ]
10107
+
10108
+ INSTRUMENTS_CLASSES = [
10109
+ {"name": "Piano", "program_range": range(8)}, # 0
10110
+ {"name": "Chromatic Percussion", "program_range": range(8, 16)},
10111
+ {"name": "Organ", "program_range": range(16, 24)},
10112
+ {"name": "Guitar", "program_range": range(24, 32)},
10113
+ {"name": "Bass", "program_range": range(32, 40)},
10114
+ {"name": "Strings", "program_range": range(40, 48)}, # 5
10115
+ {"name": "Ensemble", "program_range": range(48, 56)},
10116
+ {"name": "Brass", "program_range": range(56, 64)},
10117
+ {"name": "Reed", "program_range": range(64, 72)},
10118
+ {"name": "Pipe", "program_range": range(72, 80)},
10119
+ {"name": "Synth Lead", "program_range": range(80, 88)}, # 10
10120
+ {"name": "Synth Pad", "program_range": range(88, 96)},
10121
+ {"name": "Synth Effects", "program_range": range(96, 104)},
10122
+ {"name": "Ethnic", "program_range": range(104, 112)},
10123
+ {"name": "Percussive", "program_range": range(112, 120)},
10124
+ {"name": "Sound Effects", "program_range": range(120, 128)}, # 15
10125
+ {"name": "Drums", "program_range": range(-1, 0)},
10126
+ ]
10127
+
10128
+ # To easily get the class index of any instrument program
10129
+ CLASS_OF_INST = [
10130
+ i
10131
+ for i, inst_class in enumerate(INSTRUMENTS_CLASSES)
10132
+ for _ in inst_class["program_range"]
10133
+ ]
10134
+
10135
+ # index i = program i+1 in the GM2 specs (8. Appendix B)
10136
+ # index i = program i retrieved by packages
10137
+ DRUMS_SETS = {
10138
+ 0: "Standard",
10139
+ 8: "Room",
10140
+ 16: "Power",
10141
+ 24: "Electronic",
10142
+ 25: "Analog",
10143
+ 32: "Jazz",
10144
+ 40: "Brush",
10145
+ 48: "Orchestra",
10146
+ 56: "SFX",
10147
+ }
10148
+
10149
+ # Control changes list (without specifications):
10150
+ # https://www.midi.org/specifications-old/item/table-3-control-change-messages-data-bytes-2
10151
+ # Undefined and general control changes are not considered here
10152
+ # All these attributes can take values from 0 to 127, with some of them being on/off
10153
+ CONTROL_CHANGES = {
10154
+ # MSB
10155
+ 0: "Bank Select",
10156
+ 1: "Modulation Depth",
10157
+ 2: "Breath Controller",
10158
+ 4: "Foot Controller",
10159
+ 5: "Portamento Time",
10160
+ 6: "Data Entry",
10161
+ 7: "Channel Volume",
10162
+ 8: "Balance",
10163
+ 10: "Pan",
10164
+ 11: "Expression Controller",
10165
+ # LSB
10166
+ 32: "Bank Select",
10167
+ 33: "Modulation Depth",
10168
+ 34: "Breath Controller",
10169
+ 36: "Foot Controller",
10170
+ 37: "Portamento Time",
10171
+ 38: "Data Entry",
10172
+ 39: "Channel Volume",
10173
+ 40: "Balance",
10174
+ 42: "Pan",
10175
+ 43: "Expression Controller",
10176
+ # On / Off control changes, ≤63 off, ≥64 on
10177
+ 64: "Damper Pedal",
10178
+ 65: "Portamento",
10179
+ 66: "Sostenuto",
10180
+ 67: "Soft Pedal",
10181
+ 68: "Legato Footswitch",
10182
+ 69: "Hold 2",
10183
+ # Continuous controls
10184
+ 70: "Sound Variation",
10185
+ 71: "Timbre/Harmonic Intensity",
10186
+ 72: "Release Time",
10187
+ 73: "Attack Time",
10188
+ 74: "Brightness",
10189
+ 75: "Decay Time",
10190
+ 76: "Vibrato Rate",
10191
+ 77: "Vibrato Depth",
10192
+ 78: "Vibrato Delay",
10193
+ 84: "Portamento Control",
10194
+ 88: "High Resolution Velocity Prefix",
10195
+ # Effects depths
10196
+ 91: "Reverb Depth",
10197
+ 92: "Tremolo Depth",
10198
+ 93: "Chorus Depth",
10199
+ 94: "Celeste Depth",
10200
+ 95: "Phaser Depth",
10201
+ # Registered parameters numbers
10202
+ 96: "Data Increment",
10203
+ 97: "Data Decrement",
10204
+ # 98: 'Non-Registered Parameter Number (NRPN) - LSB',
10205
+ # 99: 'Non-Registered Parameter Number (NRPN) - MSB',
10206
+ 100: "Registered Parameter Number (RPN) - LSB",
10207
+ 101: "Registered Parameter Number (RPN) - MSB",
10208
+ # Channel mode controls
10209
+ 120: "All Sound Off",
10210
+ 121: "Reset All Controllers",
10211
+ 122: "Local Control On/Off",
10212
+ 123: "All Notes Off",
10213
+ 124: "Omni Mode Off", # + all notes off
10214
+ 125: "Omni Mode On", # + all notes off
10215
+ 126: "Mono Mode On", # + poly off, + all notes off
10216
+ 127: "Poly Mode On", # + mono off, +all notes off
10217
+ }
10218
+
10219
+ ###################################################################################
10220
+
10221
+ def patches_onset_times(escore_notes, times_idx=1, patches_idx=6):
10222
+
10223
+ patches = [e[patches_idx] for e in escore_notes]
10224
+
10225
+ patches_oset = ordered_set(patches)
10226
+
10227
+ patches_onset_times = []
10228
+
10229
+ for p in patches_oset:
10230
+ for e in escore_notes:
10231
+ if e[patches_idx] == p:
10232
+ patches_onset_times.append([p, e[times_idx]])
10233
+ break
10234
+
10235
+ return patches_onset_times
10236
+
10237
+ ###################################################################################
10238
+
10239
+ def count_escore_notes_patches(escore_notes, patches_idx=6):
10240
+
10241
+ patches = [e[patches_idx] for e in escore_notes]
10242
+
10243
+ return Counter(patches).most_common()
10244
+
10245
+ ###################################################################################
10246
+
10247
+ def escore_notes_monoponic_melodies(escore_notes,
10248
+ bad_notes_ratio=0.0,
10249
+ times_idx=1,
10250
+ patches_idx=6
10251
+ ):
10252
+
10253
+ patches = escore_notes_patches(escore_notes, patches_index=patches_idx)
10254
+
10255
+ monophonic_melodies = []
10256
+
10257
+ for p in patches:
10258
+ patch_score = [e for e in escore_notes if e[patches_idx] == p]
10259
+
10260
+ ps_times = [e[times_idx] for e in patch_score]
10261
+
10262
+ if len(ps_times) <= len(set(ps_times)) * (1+bad_notes_ratio):
10263
+ monophonic_melodies.append([p, len(patch_score)])
10264
+
10265
+ return monophonic_melodies
10266
+
10267
+ ###################################################################################
10268
+
10269
+ from itertools import groupby
10270
+ from operator import itemgetter
10271
+
10272
+ def group_by_threshold(data, threshold, groupby_idx):
10273
+
10274
+ data.sort(key=itemgetter(groupby_idx))
10275
+
10276
+ grouped_data = []
10277
+ cluster = []
10278
+
10279
+ for i, item in enumerate(data):
10280
+ if not cluster:
10281
+ cluster.append(item)
10282
+ elif abs(item[groupby_idx] - cluster[-1][groupby_idx]) <= threshold:
10283
+ cluster.append(item)
10284
+ else:
10285
+ grouped_data.append(cluster)
10286
+ cluster = [item]
10287
+
10288
+ if cluster:
10289
+ grouped_data.append(cluster)
10290
+
10291
+ return grouped_data
10292
+
10293
+ ###################################################################################
10294
+
10295
+ def split_escore_notes_by_time(escore_notes, time_threshold=256):
10296
+
10297
+ dscore = delta_score_notes(escore_notes, timings_clip_value=time_threshold-1)
10298
+
10299
+ score_chunks = []
10300
+
10301
+ ctime = 0
10302
+ pchunk_idx = 0
10303
+
10304
+ for i, e in enumerate(dscore):
10305
+
10306
+ ctime += e[1]
10307
+
10308
+ if ctime >= time_threshold:
10309
+ score_chunks.append(escore_notes[pchunk_idx:i])
10310
+ pchunk_idx = i
10311
+ ctime = 0
10312
+
10313
+ return score_chunks
10314
+
10315
+ ###################################################################################
10316
+
10317
+ def escore_notes_grouped_patches(escore_notes, time_threshold=256):
10318
+
10319
+ split_score_chunks = split_escore_notes_by_time(escore_notes,
10320
+ time_threshold=time_threshold
10321
+ )
10322
+
10323
+ chunks_patches = []
10324
+
10325
+ for s in split_score_chunks:
10326
+ chunks_patches.append(escore_notes_patches(s))
10327
+
10328
+ return chunks_patches
10329
+
10330
+ ###################################################################################
10331
+
10332
+ def computeLPSArray(pattern, M, lps):
10333
+ length = 0
10334
+ i = 1
10335
+
10336
+ lps[0] = 0
10337
+
10338
+ while i < M:
10339
+ if pattern[i] == pattern[length]:
10340
+ length += 1
10341
+ lps[i] = length
10342
+ i += 1
10343
+ else:
10344
+ if length != 0:
10345
+ length = lps[length-1]
10346
+ else:
10347
+ lps[i] = 0
10348
+ i += 1
10349
+
10350
+ ###################################################################################
10351
+
10352
+ def find_pattern_idxs(sub_pattern, pattern):
10353
+
10354
+ lst = pattern
10355
+ pattern = sub_pattern
10356
+
10357
+ M = len(pattern)
10358
+ N = len(lst)
10359
+
10360
+ lps = [0] * M
10361
+ j = 0 # index for pattern[]
10362
+
10363
+ computeLPSArray(pattern, M, lps)
10364
+
10365
+ i = 0 # index for lst[]
10366
+ indexes = []
10367
+
10368
+ while i < N:
10369
+ if pattern[j] == lst[i]:
10370
+ i += 1
10371
+ j += 1
10372
+
10373
+ if j == M:
10374
+ end_index = i - 1
10375
+ start_index = end_index - M + 1
10376
+ indexes.append((start_index, end_index))
10377
+ j = lps[j-1]
10378
+ elif i < N and pattern[j] != lst[i]:
10379
+ if j != 0:
10380
+ j = lps[j-1]
10381
+ else:
10382
+ i += 1
10383
+
10384
+ return indexes
10385
+
10386
+ ###################################################################################
10387
+
10388
+ def escore_notes_patch_lrno_patterns(escore_notes,
10389
+ patch=0,
10390
+ zero_score_timings=False,
10391
+ pitches_idx=4,
10392
+ patches_idx=6
10393
+ ):
10394
+
10395
+ patch_escore = [e for e in escore_notes if e[patches_idx] == patch]
10396
+
10397
+ if patch_escore:
10398
+
10399
+ patch_cscore = chordify_score([1000, patch_escore])
10400
+
10401
+ patch_tscore = []
10402
+
10403
+ for c in patch_cscore:
10404
+
10405
+ tones_chord = sorted(set([p[pitches_idx] % 12 for p in c]))
10406
+
10407
+ if tones_chord not in ALL_CHORDS_SORTED:
10408
+ tnoes_chord = check_and_fix_tones_chord(tones_chord)
10409
+
10410
+ patch_tscore.append(ALL_CHORDS_SORTED.index(tones_chord))
10411
+
10412
+ pattern = find_lrno_pattern_fast(patch_tscore)
10413
+
10414
+ patterns_idxs = find_pattern_idxs(pattern, patch_tscore)
10415
+
10416
+ patch_lrno_scores = []
10417
+
10418
+ for idxs in patterns_idxs:
10419
+
10420
+ score = patch_escore[idxs[0]:idxs[1]]
10421
+
10422
+ if zero_score_timings:
10423
+ score = recalculate_score_timings(score)
10424
+
10425
+ patch_lrno_scores.append(score)
10426
+
10427
+ return patch_lrno_scores
10428
+
10429
+ else:
10430
+ return []
10431
+
10432
+ ###################################################################################
10433
+
10434
+ ALL_BASE_CHORDS_SORTED = [[0], [0, 2], [0, 2, 4], [0, 2, 4, 6], [0, 2, 4, 6, 8], [0, 2, 4, 6, 8, 10],
10435
+ [0, 2, 4, 6, 9], [0, 2, 4, 6, 10], [0, 2, 4, 7], [0, 2, 4, 7, 9],
10436
+ [0, 2, 4, 7, 10], [0, 2, 4, 8], [0, 2, 4, 8, 10], [0, 2, 4, 9], [0, 2, 4, 10],
10437
+ [0, 2, 5], [0, 2, 5, 7], [0, 2, 5, 7, 9], [0, 2, 5, 7, 10], [0, 2, 5, 8],
10438
+ [0, 2, 5, 8, 10], [0, 2, 5, 9], [0, 2, 5, 10], [0, 2, 6], [0, 2, 6, 8],
10439
+ [0, 2, 6, 8, 10], [0, 2, 6, 9], [0, 2, 6, 10], [0, 2, 7], [0, 2, 7, 9],
10440
+ [0, 2, 7, 10], [0, 2, 8], [0, 2, 8, 10], [0, 2, 9], [0, 2, 10], [0, 3],
10441
+ [0, 3, 5], [0, 3, 5, 7], [0, 3, 5, 7, 9], [0, 3, 5, 7, 10], [0, 3, 5, 8],
10442
+ [0, 3, 5, 8, 10], [0, 3, 5, 9], [0, 3, 5, 10], [0, 3, 6], [0, 3, 6, 8],
10443
+ [0, 3, 6, 8, 10], [0, 3, 6, 9], [0, 3, 6, 10], [0, 3, 7], [0, 3, 7, 9],
10444
+ [0, 3, 7, 10], [0, 3, 8], [0, 3, 8, 10], [0, 3, 9], [0, 3, 10], [0, 4],
10445
+ [0, 4, 6], [0, 4, 6, 8], [0, 4, 6, 8, 10], [0, 4, 6, 9], [0, 4, 6, 10],
10446
+ [0, 4, 7], [0, 4, 7, 9], [0, 4, 7, 10], [0, 4, 8], [0, 4, 8, 10], [0, 4, 9],
10447
+ [0, 4, 10], [0, 5], [0, 5, 7], [0, 5, 7, 9], [0, 5, 7, 10], [0, 5, 8],
10448
+ [0, 5, 8, 10], [0, 5, 9], [0, 5, 10], [0, 6], [0, 6, 8], [0, 6, 8, 10],
10449
+ [0, 6, 9], [0, 6, 10], [0, 7], [0, 7, 9], [0, 7, 10], [0, 8], [0, 8, 10],
10450
+ [0, 9], [0, 10]]
10451
+
10452
+ ###################################################################################
10453
+
10454
+ MAJOR_SCALE_CHORDS_COUNTS = [[317, 6610], [320, 6468], [267, 6460], [89, 6329], [301, 6228], [178, 6201],
10455
+ [0, 5822], [314, 5805], [309, 5677], [319, 5545], [288, 5494], [233, 5395],
10456
+ [112, 2232], [194, 1956], [127, 1935], [216, 1884], [256, 1871], [283, 1815],
10457
+ [201, 1768], [16, 1756], [105, 1743], [38, 1727], [23, 1718], [249, 1386],
10458
+ [272, 796], [91, 770], [191, 740], [303, 735], [181, 718], [306, 717],
10459
+ [235, 703], [183, 690], [94, 686], [13, 686], [269, 677], [280, 675],
10460
+ [102, 665], [92, 662], [293, 659], [212, 658], [114, 656], [37, 653],
10461
+ [180, 651], [215, 644], [316, 640], [290, 636], [5, 636], [110, 625],
10462
+ [270, 625], [3, 624], [238, 615], [123, 609], [34, 591], [254, 584],
10463
+ [258, 571], [126, 567], [2, 559], [246, 556], [104, 556], [203, 550],
10464
+ [291, 537], [311, 522], [304, 520], [193, 509], [236, 496], [199, 493],
10465
+ [15, 468], [25, 452], [312, 444], [282, 443], [248, 433], [21, 408],
10466
+ [268, 281], [179, 273], [144, 259], [90, 252], [162, 250], [234, 250],
10467
+ [1, 246], [221, 214], [73, 213], [43, 213], [45, 213], [134, 212], [318, 210],
10468
+ [119, 210], [159, 209], [120, 209], [302, 207], [310, 201], [289, 195],
10469
+ [42, 193], [264, 193], [220, 185], [131, 183], [55, 180], [315, 180],
10470
+ [132, 176], [30, 174], [31, 172], [209, 171], [227, 169], [217, 163],
10471
+ [223, 159], [70, 158], [39, 157], [36, 153], [214, 142], [196, 141],
10472
+ [285, 141], [8, 137], [208, 133], [125, 133], [147, 130], [186, 130],
10473
+ [97, 130], [49, 130], [58, 130], [128, 130], [138, 128], [241, 125],
10474
+ [228, 124], [263, 120], [251, 120], [275, 119], [296, 118], [259, 116],
10475
+ [99, 114], [10, 113], [50, 111], [273, 111], [139, 111], [298, 106], [18, 105],
10476
+ [153, 105], [7, 101], [277, 101], [243, 99], [96, 99], [9, 96], [160, 96],
10477
+ [188, 95], [115, 94], [24, 93], [107, 92], [204, 90], [150, 90], [148, 84],
10478
+ [202, 83], [213, 82], [187, 82], [35, 80], [113, 79], [98, 78], [239, 77],
10479
+ [59, 77], [26, 76], [281, 76], [184, 75], [64, 75], [124, 75], [71, 75],
10480
+ [257, 75], [95, 74], [294, 73], [192, 70], [247, 70], [61, 67], [307, 66],
10481
+ [242, 65], [218, 65], [146, 64], [276, 63], [6, 63], [68, 60], [284, 59],
10482
+ [103, 59], [297, 56], [14, 56], [185, 55], [57, 55], [40, 55], [129, 54],
10483
+ [274, 52], [308, 52], [46, 51], [224, 49], [240, 47], [135, 46], [17, 45],
10484
+ [295, 45], [106, 45], [48, 44], [157, 44], [206, 43], [195, 42], [158, 42],
10485
+ [69, 41], [117, 41], [225, 40], [222, 37], [226, 35], [261, 34], [164, 32],
10486
+ [75, 32], [28, 32], [11, 32], [250, 31], [44, 30], [137, 28], [47, 26],
10487
+ [133, 26], [255, 25], [182, 24], [136, 24], [197, 23], [93, 23], [237, 22],
10488
+ [287, 22], [165, 22], [79, 21], [271, 21], [109, 21], [253, 20], [76, 20],
10489
+ [168, 19], [155, 19], [149, 19], [108, 19], [4, 18], [51, 18], [292, 18],
10490
+ [198, 18], [41, 17], [286, 17], [19, 17], [219, 17], [173, 17], [66, 16],
10491
+ [54, 16], [229, 16], [140, 16], [175, 15], [171, 15], [82, 15], [130, 15],
10492
+ [20, 15], [230, 15], [244, 14], [145, 14], [84, 14], [305, 14], [278, 14],
10493
+ [86, 13], [60, 13], [232, 12], [100, 12], [141, 12], [52, 12], [189, 12],
10494
+ [252, 12], [56, 11], [53, 11], [143, 10], [151, 10], [154, 10], [163, 9],
10495
+ [116, 9], [27, 9], [65, 9], [313, 9], [205, 9], [170, 8], [62, 8], [299, 7],
10496
+ [142, 7], [231, 7], [156, 6], [22, 6], [63, 6], [152, 6], [77, 5], [67, 5],
10497
+ [166, 5], [174, 5], [85, 4], [72, 4], [190, 4], [111, 4], [101, 4], [200, 4],
10498
+ [12, 4], [245, 3], [300, 3], [279, 3], [81, 2], [210, 2], [32, 2], [265, 2],
10499
+ [260, 2], [74, 2], [161, 1], [207, 1], [29, 1], [118, 1], [262, 1], [121, 1]]
10500
+
10501
+ ###################################################################################
10502
+
10503
+ MINOR_SCALE_CHORDS_COUNTS = [[267, 10606], [89, 10562], [301, 10522], [320, 10192], [178, 10191],
10504
+ [317, 10153], [233, 10101], [314, 10065], [288, 9914], [0, 9884], [309, 9694],
10505
+ [319, 9648], [114, 1963], [193, 1778], [25, 1705], [104, 1689], [248, 1671],
10506
+ [282, 1614], [283, 1610], [127, 1530], [203, 1525], [37, 1508], [215, 1473],
10507
+ [105, 1465], [38, 1462], [258, 1445], [112, 1419], [94, 1413], [280, 1391],
10508
+ [194, 1388], [126, 1384], [16, 1374], [272, 1370], [23, 1364], [238, 1351],
10509
+ [306, 1342], [303, 1340], [5, 1338], [183, 1334], [102, 1333], [290, 1322],
10510
+ [269, 1312], [191, 1311], [249, 1305], [15, 1291], [246, 1290], [316, 1288],
10511
+ [13, 1279], [216, 1278], [235, 1275], [256, 1268], [311, 1241], [293, 1228],
10512
+ [91, 1219], [180, 1173], [34, 1167], [2, 1138], [212, 1131], [123, 1118],
10513
+ [201, 1103], [270, 1017], [304, 961], [181, 958], [92, 943], [3, 940],
10514
+ [236, 932], [254, 923], [291, 921], [110, 920], [21, 911], [312, 891],
10515
+ [199, 832], [268, 431], [179, 395], [234, 395], [302, 385], [144, 368],
10516
+ [90, 365], [289, 362], [310, 352], [318, 350], [1, 332], [55, 323], [315, 322],
10517
+ [8, 307], [162, 304], [97, 302], [186, 302], [241, 300], [10, 299], [217, 289],
10518
+ [275, 275], [128, 267], [73, 266], [243, 265], [125, 262], [296, 259],
10519
+ [298, 251], [36, 250], [39, 250], [99, 249], [214, 231], [119, 230],
10520
+ [120, 227], [188, 227], [159, 226], [264, 225], [263, 225], [138, 223],
10521
+ [31, 222], [227, 219], [134, 216], [277, 214], [70, 210], [209, 207],
10522
+ [30, 203], [49, 186], [46, 185], [45, 184], [221, 172], [281, 170], [96, 169],
10523
+ [131, 169], [224, 165], [148, 159], [59, 157], [43, 157], [7, 157], [247, 155],
10524
+ [208, 153], [132, 152], [274, 150], [223, 149], [135, 148], [273, 148],
10525
+ [240, 137], [220, 132], [185, 131], [239, 131], [42, 130], [147, 119],
10526
+ [213, 117], [307, 115], [24, 112], [95, 108], [192, 107], [150, 106],
10527
+ [294, 105], [106, 104], [58, 102], [103, 102], [17, 100], [129, 100], [61, 99],
10528
+ [9, 98], [139, 96], [295, 96], [284, 96], [146, 96], [218, 95], [184, 94],
10529
+ [308, 87], [195, 87], [40, 86], [14, 85], [50, 82], [250, 82], [285, 81],
10530
+ [57, 79], [259, 79], [6, 79], [276, 78], [228, 78], [35, 76], [187, 75],
10531
+ [242, 73], [206, 73], [160, 72], [113, 72], [117, 72], [261, 72], [98, 71],
10532
+ [202, 70], [115, 70], [158, 69], [71, 68], [48, 67], [28, 67], [204, 66],
10533
+ [157, 64], [124, 63], [257, 59], [196, 59], [69, 59], [68, 57], [251, 55],
10534
+ [225, 50], [137, 50], [107, 49], [165, 49], [297, 48], [64, 46], [153, 45],
10535
+ [226, 44], [198, 44], [287, 43], [26, 43], [219, 41], [253, 40], [109, 40],
10536
+ [66, 39], [47, 39], [41, 39], [76, 38], [11, 38], [136, 38], [130, 36],
10537
+ [155, 35], [18, 31], [93, 31], [20, 30], [271, 29], [4, 28], [292, 28],
10538
+ [237, 27], [182, 26], [62, 26], [164, 25], [151, 25], [108, 25], [286, 24],
10539
+ [145, 24], [305, 24], [75, 24], [56, 23], [149, 23], [252, 23], [197, 23],
10540
+ [255, 23], [313, 21], [60, 18], [244, 17], [278, 17], [189, 17], [100, 16],
10541
+ [299, 15], [200, 13], [175, 13], [111, 13], [22, 13], [170, 12], [232, 11],
10542
+ [86, 11], [141, 11], [52, 11], [65, 10], [173, 10], [133, 10], [222, 10],
10543
+ [143, 10], [154, 9], [82, 8], [19, 8], [85, 8], [44, 8], [84, 8], [163, 7],
10544
+ [205, 7], [230, 7], [54, 7], [174, 7], [116, 7], [27, 7], [171, 7], [229, 6],
10545
+ [81, 5], [79, 4], [142, 4], [231, 4], [210, 3], [168, 3], [53, 3], [51, 3],
10546
+ [74, 3], [265, 3], [260, 3], [152, 2], [245, 2], [279, 2], [190, 2], [12, 2],
10547
+ [101, 2], [262, 1], [63, 1], [72, 1], [207, 1], [166, 1], [83, 1], [176, 1],
10548
+ [118, 1], [67, 1], [172, 1], [29, 1], [121, 1], [77, 1], [266, 1], [156, 1],
10549
+ [211, 1], [300, 1], [87, 1], [140, 1], [161, 1]]
10550
+
10551
+ ###################################################################################
10552
+
10553
+ def get_weighted_score(src_order, trg_order):
10554
+
10555
+ score = 0
10556
+
10557
+ for i, (item, count) in enumerate(src_order):
10558
+ if item in trg_order:
10559
+ score += count * abs(i - trg_order.index(item))
10560
+
10561
+ else:
10562
+ score += count * len(trg_order)
10563
+
10564
+ return score
10565
+
10566
+ ###################################################################################
10567
+
10568
+ def escore_notes_scale(escore_notes,
10569
+ score_mult_factor=3,
10570
+ start_note=0,
10571
+ num_notes=-1,
10572
+ return_scale_indexes=False
10573
+ ):
10574
+
10575
+ trg_chords = []
10576
+
10577
+ for i in range(-score_mult_factor, score_mult_factor):
10578
+
10579
+ trans_escore_notes = transpose_escore_notes(escore_notes[start_note:start_note+num_notes], i)
10580
+
10581
+ cscore = chordify_score([1000, trans_escore_notes])
10582
+
10583
+ tones_chords = []
10584
+
10585
+ for c in cscore:
10586
+
10587
+ seen = []
10588
+ pitches = []
10589
+
10590
+ for e in c:
10591
+
10592
+ if e[4] not in seen:
10593
+ pitches.append(e[4])
10594
+ seen.append(e[4])
10595
+
10596
+ if pitches:
10597
+
10598
+ tones_chord = sorted(set([p % 12 for p in pitches]))
10599
+
10600
+ if tones_chord not in ALL_CHORDS_SORTED:
10601
+ tones_chord = check_and_fix_tones_chord(tones_chord)
10602
+
10603
+ tones_chords.append(ALL_CHORDS_SORTED.index(tones_chord))
10604
+
10605
+ if tones_chords:
10606
+ trg_chords.extend(tones_chords)
10607
+
10608
+ #========================================================================
10609
+
10610
+ scales_results = []
10611
+
10612
+ #========================================================================
10613
+
10614
+ if trg_chords:
10615
+
10616
+ #========================================================================
10617
+
10618
+ src_order = Counter(trg_chords).most_common()
10619
+
10620
+ trg1_items = [item for item, count in MAJOR_SCALE_CHORDS_COUNTS]
10621
+ trg2_items = [item for item, count in MINOR_SCALE_CHORDS_COUNTS]
10622
+
10623
+
10624
+ trg1_score = get_weighted_score(src_order, trg1_items)
10625
+ trg2_score = get_weighted_score(src_order, trg2_items)
10626
+
10627
+ #========================================================================
10628
+
10629
+ if trg1_score <= trg2_score:
10630
+
10631
+ if return_scale_indexes:
10632
+ scales_results.append(1)
10633
+
10634
+ else:
10635
+ scales_results.append('Major')
10636
+
10637
+ else:
10638
+ if return_scale_indexes:
10639
+ scales_results.append(0)
10640
+
10641
+ else:
10642
+ scales_results.append('Minor')
10643
+
10644
+ #========================================================================
10645
+
10646
+ best_match = None
10647
+ best_score = float('inf')
10648
+
10649
+ for trg_order in ALL_MOOD_TYPES:
10650
+
10651
+ trg_items = [item for item, count in trg_order]
10652
+
10653
+ trg_score = get_weighted_score(src_order, trg_items)
10654
+
10655
+ if trg_score < best_score:
10656
+ best_score = trg_score
10657
+
10658
+ if return_scale_indexes:
10659
+ best_match = ALL_MOOD_TYPES.index(trg_order)
10660
+
10661
+ else:
10662
+ best_match = ALL_MOOD_TYPES_LABELS[ALL_MOOD_TYPES.index(trg_order)]
10663
+
10664
+ scales_results.append(best_match)
10665
+
10666
+ else:
10667
+ if return_scale_indexes:
10668
+ scales_results.extend([-1, -1])
10669
+
10670
+ else:
10671
+ scales_results.extend(['Unknown', 'Unknown'])
10672
+
10673
+ return scales_results
10674
+
10675
+ ###################################################################################
10676
+
10677
+ HAPPY_MAJOR = [(317, 1916), (89, 1876), (320, 1840), (267, 1817), (301, 1795), (178, 1750),
10678
+ (314, 1725), (0, 1691), (319, 1658), (288, 1624), (309, 1599), (233, 1559),
10679
+ (112, 1050), (127, 972), (201, 884), (194, 879), (216, 860), (38, 831),
10680
+ (256, 828), (23, 822), (105, 820), (283, 756), (16, 734), (249, 622),
10681
+ (91, 254), (303, 242), (34, 237), (316, 235), (110, 235), (123, 234),
10682
+ (212, 230), (92, 225), (181, 225), (114, 219), (272, 218), (290, 213),
10683
+ (235, 208), (180, 207), (269, 206), (2, 201), (3, 199), (203, 198), (37, 195),
10684
+ (254, 191), (199, 189), (311, 189), (293, 187), (5, 186), (270, 185),
10685
+ (183, 184), (291, 183), (94, 183), (25, 182), (304, 181), (258, 176),
10686
+ (215, 173), (191, 172), (193, 168), (104, 167), (282, 164), (238, 162),
10687
+ (248, 157), (15, 156), (13, 156), (126, 153), (21, 150), (102, 150),
10688
+ (306, 150), (312, 144), (280, 141), (236, 139), (162, 116), (120, 114),
10689
+ (246, 113), (134, 109), (43, 108), (221, 105), (264, 103), (73, 100),
10690
+ (159, 98), (42, 95), (45, 94), (220, 93), (131, 91), (119, 91), (227, 90),
10691
+ (209, 88), (70, 86), (144, 86), (31, 85), (223, 84), (58, 82), (1, 80),
10692
+ (132, 79), (30, 76), (90, 75), (268, 75), (259, 74), (234, 72), (179, 72),
10693
+ (147, 70), (318, 69), (208, 67), (315, 66), (55, 66), (49, 64), (310, 63),
10694
+ (138, 62), (214, 61), (263, 60), (204, 59), (302, 58), (196, 58), (115, 56),
10695
+ (107, 53), (18, 53), (153, 52), (289, 52), (9, 50), (10, 50), (217, 49),
10696
+ (243, 48), (39, 48), (99, 48), (7, 47), (188, 46), (26, 46), (68, 46),
10697
+ (36, 45), (125, 43), (202, 43), (285, 42), (24, 42), (277, 41), (98, 40),
10698
+ (251, 39), (113, 39), (8, 38), (128, 38), (187, 37), (35, 36), (213, 36),
10699
+ (97, 35), (186, 35), (61, 34), (150, 34), (160, 33), (124, 32), (96, 32),
10700
+ (257, 32), (275, 31), (241, 31), (296, 30), (64, 30), (297, 29), (298, 29),
10701
+ (117, 29), (46, 28), (273, 28), (206, 28), (157, 27), (242, 26), (224, 26),
10702
+ (185, 26), (222, 26), (59, 25), (135, 24), (158, 23), (28, 23), (294, 22),
10703
+ (69, 22), (276, 21), (274, 21), (225, 21), (148, 20), (50, 20), (48, 20),
10704
+ (281, 19), (139, 19), (307, 19), (228, 19), (75, 18), (164, 18), (44, 18),
10705
+ (133, 18), (79, 17), (184, 17), (57, 17), (240, 17), (239, 17), (295, 17),
10706
+ (247, 16), (95, 16), (261, 15), (308, 15), (287, 14), (76, 14), (165, 14),
10707
+ (175, 14), (82, 14), (284, 14), (71, 14), (253, 12), (155, 12), (86, 12),
10708
+ (4, 12), (93, 12), (171, 12), (137, 12), (66, 11), (232, 11), (168, 11),
10709
+ (103, 11), (192, 11), (54, 10), (145, 10), (40, 10), (51, 10), (182, 10),
10710
+ (226, 10), (14, 10), (129, 9), (218, 9), (146, 9), (237, 9), (19, 9), (108, 9),
10711
+ (197, 9), (140, 8), (229, 8), (6, 7), (17, 7), (56, 6), (106, 6), (271, 6),
10712
+ (109, 6), (163, 5), (143, 5), (65, 5), (154, 5), (27, 5), (116, 5), (205, 5),
10713
+ (195, 5), (250, 5), (198, 5), (41, 5), (136, 5), (47, 4), (52, 4), (141, 4),
10714
+ (230, 4), (84, 4), (173, 4), (255, 4), (11, 4), (100, 4), (189, 4), (244, 4),
10715
+ (278, 4), (219, 3), (20, 3), (286, 3), (130, 3), (170, 3), (151, 3), (53, 2),
10716
+ (77, 2), (166, 2), (67, 2), (156, 2), (63, 2), (60, 2), (292, 2), (62, 2),
10717
+ (142, 1), (231, 1), (85, 1), (174, 1), (81, 1), (152, 1), (262, 1), (72, 1),
10718
+ (161, 1), (29, 1), (118, 1), (207, 1), (149, 1), (300, 1), (299, 1), (252, 1)]
10719
+
10720
+ ###################################################################################
10721
+
10722
+ MELANCHOLIC_MAJOR = [(317, 451), (301, 430), (89, 426), (320, 419), (267, 416), (178, 415),
10723
+ (314, 401), (319, 400), (0, 394), (309, 390), (288, 389), (233, 365),
10724
+ (37, 224), (215, 207), (258, 203), (126, 191), (114, 185), (203, 183),
10725
+ (283, 141), (127, 131), (38, 127), (216, 115), (194, 113), (112, 112),
10726
+ (23, 109), (105, 105), (249, 103), (16, 99), (306, 96), (256, 92), (13, 87),
10727
+ (280, 86), (181, 86), (102, 85), (92, 84), (104, 84), (15, 84), (191, 83),
10728
+ (246, 83), (270, 81), (94, 74), (3, 73), (238, 72), (272, 72), (236, 72),
10729
+ (201, 72), (183, 70), (293, 66), (193, 63), (254, 63), (212, 61), (282, 60),
10730
+ (123, 58), (5, 57), (25, 55), (291, 53), (34, 52), (316, 50), (304, 48),
10731
+ (91, 47), (2, 47), (110, 46), (248, 45), (303, 38), (311, 38), (45, 36),
10732
+ (180, 35), (199, 34), (235, 33), (162, 33), (221, 33), (21, 32), (144, 32),
10733
+ (132, 31), (179, 29), (90, 29), (43, 29), (217, 29), (312, 28), (39, 28),
10734
+ (128, 28), (302, 27), (268, 27), (36, 27), (125, 27), (269, 26), (134, 26),
10735
+ (234, 26), (73, 25), (318, 25), (55, 25), (1, 24), (290, 23), (8, 22),
10736
+ (310, 22), (315, 22), (97, 20), (186, 20), (241, 20), (275, 20), (296, 20),
10737
+ (289, 20), (119, 18), (298, 18), (31, 17), (6, 17), (95, 17), (184, 17),
10738
+ (273, 17), (223, 16), (276, 15), (120, 15), (239, 15), (30, 15), (208, 14),
10739
+ (59, 14), (159, 13), (146, 13), (42, 13), (209, 13), (26, 13), (264, 13),
10740
+ (147, 13), (187, 13), (242, 13), (115, 12), (220, 12), (70, 12), (226, 12),
10741
+ (47, 12), (148, 12), (24, 11), (49, 11), (131, 10), (227, 10), (214, 10),
10742
+ (136, 9), (225, 9), (69, 9), (138, 9), (158, 9), (106, 9), (98, 9), (257, 8),
10743
+ (263, 8), (297, 8), (50, 8), (204, 8), (259, 8), (7, 8), (294, 8), (281, 8),
10744
+ (9, 8), (113, 7), (202, 7), (17, 7), (124, 7), (213, 7), (57, 7), (96, 7),
10745
+ (247, 7), (285, 6), (185, 6), (130, 6), (219, 6), (218, 6), (58, 6), (139, 5),
10746
+ (35, 5), (240, 5), (195, 5), (250, 5), (20, 5), (284, 5), (150, 5), (261, 5),
10747
+ (48, 5), (107, 4), (196, 4), (251, 4), (292, 4), (41, 4), (228, 4), (61, 4),
10748
+ (71, 4), (160, 4), (109, 4), (103, 4), (192, 4), (206, 4), (137, 4), (274, 3),
10749
+ (18, 3), (305, 3), (295, 3), (93, 3), (308, 3), (182, 3), (237, 3), (271, 3),
10750
+ (198, 3), (168, 3), (51, 3), (140, 3), (229, 3), (54, 3), (155, 3), (10, 3),
10751
+ (99, 3), (157, 2), (64, 2), (143, 2), (224, 2), (253, 2), (307, 2), (66, 2),
10752
+ (40, 2), (129, 2), (188, 2), (11, 2), (243, 2), (28, 1), (117, 1), (4, 1),
10753
+ (313, 1), (62, 1), (151, 1), (56, 1), (135, 1), (46, 1), (165, 1), (79, 1),
10754
+ (299, 1), (60, 1), (149, 1), (22, 1), (111, 1), (200, 1)]
10755
+
10756
+ ###################################################################################
10757
+
10758
+ MELANCHOLIC_MINOR = [(89, 3681), (267, 3628), (317, 3472), (301, 3408), (320, 3290), (178, 3261),
10759
+ (314, 3261), (288, 3206), (0, 3140), (233, 3050), (319, 2894), (309, 2841),
10760
+ (114, 570), (283, 559), (104, 544), (193, 529), (215, 509), (37, 507),
10761
+ (127, 482), (126, 468), (38, 456), (282, 432), (248, 417), (25, 415),
10762
+ (194, 414), (216, 412), (112, 411), (258, 407), (23, 403), (105, 399),
10763
+ (249, 399), (303, 387), (203, 386), (15, 366), (256, 356), (16, 351),
10764
+ (290, 343), (316, 343), (269, 332), (235, 323), (91, 312), (311, 296),
10765
+ (272, 286), (34, 273), (94, 271), (180, 269), (212, 265), (123, 260),
10766
+ (306, 259), (270, 254), (102, 246), (201, 246), (238, 246), (280, 242),
10767
+ (110, 236), (183, 236), (191, 232), (293, 230), (5, 228), (2, 228), (291, 226),
10768
+ (304, 225), (13, 219), (312, 207), (21, 207), (181, 203), (92, 195),
10769
+ (246, 192), (3, 191), (254, 181), (236, 173), (199, 155), (268, 124),
10770
+ (179, 114), (144, 103), (90, 103), (302, 102), (318, 101), (234, 99),
10771
+ (289, 86), (1, 84), (310, 83), (31, 79), (120, 79), (55, 78), (315, 72),
10772
+ (162, 72), (264, 71), (73, 70), (209, 69), (159, 61), (227, 61), (263, 60),
10773
+ (49, 58), (138, 57), (119, 51), (273, 49), (70, 49), (10, 47), (8, 44),
10774
+ (97, 44), (186, 44), (241, 44), (275, 44), (99, 44), (146, 43), (239, 42),
10775
+ (296, 39), (214, 39), (217, 39), (95, 38), (148, 37), (36, 36), (281, 34),
10776
+ (307, 33), (125, 33), (218, 32), (59, 31), (134, 31), (160, 31), (184, 31),
10777
+ (129, 29), (208, 29), (223, 29), (71, 29), (30, 29), (96, 27), (147, 27),
10778
+ (228, 27), (57, 27), (6, 27), (284, 26), (50, 26), (139, 26), (247, 24),
10779
+ (24, 24), (250, 24), (115, 24), (204, 24), (259, 24), (9, 23), (240, 23),
10780
+ (274, 23), (220, 23), (58, 23), (103, 22), (40, 22), (131, 22), (243, 22),
10781
+ (106, 22), (285, 22), (46, 22), (295, 21), (308, 21), (221, 21), (14, 20),
10782
+ (45, 20), (42, 20), (195, 20), (294, 19), (188, 19), (277, 19), (185, 18),
10783
+ (192, 18), (17, 18), (135, 18), (224, 18), (7, 17), (61, 17), (150, 16),
10784
+ (225, 14), (69, 14), (158, 14), (128, 14), (257, 14), (149, 13), (64, 13),
10785
+ (298, 13), (39, 13), (213, 12), (113, 12), (43, 11), (132, 11), (28, 11),
10786
+ (35, 10), (124, 10), (47, 10), (136, 10), (41, 10), (130, 10), (157, 10),
10787
+ (202, 10), (165, 10), (66, 9), (155, 9), (219, 9), (153, 9), (18, 9), (255, 9),
10788
+ (11, 9), (60, 8), (22, 8), (111, 8), (107, 8), (299, 7), (143, 7), (232, 7),
10789
+ (86, 7), (175, 7), (276, 6), (313, 6), (56, 6), (62, 6), (278, 6), (151, 6),
10790
+ (26, 6), (117, 6), (206, 6), (196, 6), (98, 5), (187, 5), (242, 5), (200, 5),
10791
+ (109, 5), (198, 5), (229, 5), (54, 5), (305, 5), (261, 5), (48, 5), (76, 5),
10792
+ (226, 5), (145, 4), (20, 4), (251, 4), (68, 4), (292, 4), (253, 4), (287, 4),
10793
+ (244, 3), (4, 3), (189, 3), (93, 2), (182, 2), (237, 2), (297, 2), (100, 2),
10794
+ (173, 2), (53, 2), (142, 2), (231, 2), (85, 2), (174, 2), (271, 2), (137, 2),
10795
+ (82, 2), (171, 2), (164, 1), (44, 1), (133, 1), (222, 1), (163, 1), (65, 1),
10796
+ (154, 1), (27, 1), (116, 1), (205, 1)]
10797
+
10798
+ ###################################################################################
10799
+
10800
+ NEUTRAL_MAJOR = [(320, 574), (89, 542), (0, 535), (317, 488), (319, 458), (314, 439),
10801
+ (178, 424), (267, 405), (233, 375), (301, 330), (309, 321), (288, 287),
10802
+ (283, 77), (112, 76), (38, 71), (23, 67), (216, 61), (127, 59), (291, 54),
10803
+ (316, 52), (269, 51), (290, 51), (34, 50), (303, 50), (110, 49), (280, 47),
10804
+ (13, 45), (311, 44), (306, 43), (238, 43), (272, 43), (3, 42), (21, 42),
10805
+ (16, 41), (270, 41), (183, 39), (102, 39), (92, 39), (312, 37), (105, 37),
10806
+ (194, 37), (199, 35), (191, 35), (246, 35), (5, 35), (181, 34), (304, 34),
10807
+ (94, 33), (293, 31), (91, 29), (268, 27), (236, 27), (256, 27), (144, 24),
10808
+ (90, 24), (179, 23), (234, 23), (302, 23), (235, 23), (2, 23), (318, 22),
10809
+ (1, 22), (254, 22), (123, 22), (315, 22), (212, 22), (249, 22), (8, 21),
10810
+ (97, 21), (186, 21), (241, 21), (289, 21), (180, 21), (310, 21), (201, 21),
10811
+ (104, 20), (214, 19), (55, 18), (296, 17), (275, 17), (36, 17), (125, 17),
10812
+ (193, 16), (58, 16), (147, 16), (10, 15), (37, 14), (215, 14), (15, 14),
10813
+ (25, 14), (114, 14), (217, 13), (282, 12), (259, 12), (9, 12), (98, 12),
10814
+ (187, 12), (99, 11), (126, 10), (248, 10), (188, 10), (243, 10), (277, 10),
10815
+ (264, 10), (96, 10), (73, 10), (162, 10), (43, 10), (128, 10), (203, 8),
10816
+ (150, 8), (221, 8), (39, 8), (24, 8), (113, 8), (274, 6), (295, 6), (308, 6),
10817
+ (159, 6), (258, 6), (120, 6), (42, 6), (131, 6), (220, 6), (30, 6), (132, 6),
10818
+ (7, 6), (298, 6), (119, 6), (228, 4), (185, 4), (71, 4), (240, 4), (160, 4),
10819
+ (153, 4), (18, 4), (61, 4), (35, 4), (285, 4), (209, 4), (95, 4), (307, 4),
10820
+ (146, 4), (184, 4), (239, 4), (202, 4), (247, 4), (273, 4), (257, 4), (281, 4),
10821
+ (64, 2), (156, 2), (50, 2), (63, 2), (45, 2), (139, 2), (152, 2), (134, 2),
10822
+ (124, 2), (107, 2), (12, 2), (11, 2), (223, 2), (213, 2), (196, 2), (101, 2),
10823
+ (31, 2), (251, 2), (190, 2), (106, 2), (40, 2), (195, 2), (6, 2), (129, 2),
10824
+ (250, 2), (218, 2), (284, 2), (294, 2), (57, 2), (59, 2), (148, 2)]
10825
+
10826
+ ###################################################################################
10827
+
10828
+ NEUTRAL_MINOR = [(317, 530), (301, 499), (267, 454), (309, 438), (314, 422), (288, 420),
10829
+ (178, 415), (320, 414), (89, 399), (319, 383), (0, 341), (233, 307),
10830
+ (215, 133), (37, 127), (212, 123), (193, 121), (123, 121), (34, 119),
10831
+ (191, 117), (126, 115), (104, 108), (112, 107), (272, 105), (23, 102),
10832
+ (15, 96), (127, 92), (38, 87), (283, 85), (102, 84), (91, 83), (94, 83),
10833
+ (306, 82), (216, 80), (2, 80), (280, 79), (293, 78), (5, 78), (13, 77),
10834
+ (183, 76), (114, 74), (316, 69), (105, 68), (180, 64), (201, 62), (256, 58),
10835
+ (16, 56), (246, 55), (203, 55), (303, 52), (194, 52), (282, 49), (311, 49),
10836
+ (248, 47), (238, 43), (258, 41), (249, 39), (7, 32), (10, 29), (96, 29),
10837
+ (25, 28), (125, 27), (214, 27), (36, 26), (134, 23), (99, 22), (310, 22),
10838
+ (270, 21), (291, 20), (223, 20), (302, 20), (213, 19), (185, 19), (217, 19),
10839
+ (3, 19), (221, 19), (45, 18), (268, 16), (289, 16), (235, 15), (179, 14),
10840
+ (234, 14), (181, 14), (312, 13), (240, 13), (21, 13), (274, 13), (110, 13),
10841
+ (92, 13), (236, 13), (31, 13), (120, 13), (304, 12), (269, 11), (113, 11),
10842
+ (150, 10), (43, 10), (132, 10), (68, 9), (157, 9), (202, 9), (55, 9), (144, 9),
10843
+ (315, 9), (318, 9), (42, 9), (131, 9), (188, 8), (70, 8), (159, 8), (241, 7),
10844
+ (275, 7), (296, 7), (8, 7), (290, 7), (97, 7), (186, 7), (24, 7), (119, 7),
10845
+ (227, 7), (254, 6), (219, 6), (35, 6), (273, 6), (124, 6), (294, 6), (247, 6),
10846
+ (220, 6), (281, 6), (208, 6), (46, 6), (61, 6), (243, 5), (199, 5), (128, 5),
10847
+ (30, 5), (11, 5), (218, 5), (192, 5), (162, 5), (257, 5), (138, 5), (264, 5),
10848
+ (148, 4), (41, 4), (130, 4), (39, 4), (307, 4), (40, 4), (129, 4), (17, 4),
10849
+ (106, 4), (195, 4), (224, 4), (135, 4), (209, 4), (276, 3), (297, 3), (26, 3),
10850
+ (115, 3), (277, 3), (20, 3), (109, 3), (198, 3), (6, 3), (298, 3), (95, 3),
10851
+ (184, 3), (1, 3), (165, 3), (66, 3), (155, 3), (73, 3), (69, 3), (158, 3),
10852
+ (71, 3), (160, 3), (64, 3), (153, 3), (18, 3), (107, 3), (187, 2), (242, 2),
10853
+ (59, 2), (239, 2), (226, 2), (163, 2), (14, 2), (65, 2), (263, 2), (103, 2),
10854
+ (154, 2), (49, 2), (27, 2), (253, 2), (116, 2), (287, 2), (205, 2), (4, 1),
10855
+ (93, 1), (182, 1), (237, 1), (271, 1), (292, 1), (222, 1), (19, 1), (108, 1),
10856
+ (197, 1), (57, 1), (146, 1), (143, 1), (211, 1), (232, 1), (266, 1), (47, 1),
10857
+ (86, 1), (87, 1), (136, 1), (175, 1), (176, 1), (225, 1), (82, 1), (83, 1),
10858
+ (171, 1), (172, 1), (117, 1), (206, 1), (261, 1), (48, 1), (137, 1), (90, 1),
10859
+ (204, 1), (250, 1), (259, 1), (284, 1)]
10860
+
10861
+ ###################################################################################
10862
+
10863
+ SAD_MAJOR = [(267, 46), (301, 45), (178, 43), (89, 37), (288, 35), (233, 35), (215, 34),
10864
+ (317, 32), (320, 32), (309, 30), (314, 24), (0, 22), (319, 21), (114, 19),
10865
+ (203, 19), (258, 19), (37, 19), (193, 18), (126, 18), (15, 17), (104, 17),
10866
+ (248, 16), (282, 16), (112, 13), (134, 13), (105, 10), (221, 10), (194, 10),
10867
+ (45, 10), (162, 8), (43, 8), (201, 8), (132, 8), (256, 8), (16, 8), (127, 7),
10868
+ (283, 6), (38, 6), (306, 5), (223, 5), (216, 5), (31, 5), (23, 5), (120, 5),
10869
+ (272, 4), (123, 4), (293, 4), (119, 3), (181, 3), (125, 3), (94, 3), (236, 3),
10870
+ (212, 3), (183, 3), (270, 3), (2, 3), (238, 3), (291, 3), (91, 3), (304, 3),
10871
+ (209, 3), (312, 3), (264, 3), (163, 2), (148, 2), (157, 2), (316, 2), (217, 2),
10872
+ (13, 2), (65, 2), (208, 2), (7, 2), (214, 2), (34, 2), (36, 2), (102, 2),
10873
+ (154, 2), (249, 2), (263, 2), (96, 2), (10, 2), (191, 2), (27, 2), (49, 2),
10874
+ (99, 2), (116, 2), (138, 2), (180, 2), (205, 2), (227, 2), (235, 2), (226, 1),
10875
+ (298, 1), (307, 1), (213, 1), (159, 1), (292, 1), (144, 1), (147, 1), (290, 1),
10876
+ (47, 1), (39, 1), (40, 1), (42, 1), (305, 1), (68, 1), (1, 1), (9, 1),
10877
+ (303, 1), (136, 1), (128, 1), (129, 1), (131, 1), (313, 1), (90, 1), (98, 1),
10878
+ (311, 1), (225, 1), (218, 1), (185, 1), (220, 1), (62, 1), (179, 1), (187, 1),
10879
+ (59, 1), (246, 1), (69, 1), (57, 1), (247, 1), (240, 1), (30, 1), (151, 1),
10880
+ (188, 1), (239, 1), (234, 1), (242, 1), (280, 1), (158, 1), (146, 1), (281, 1),
10881
+ (274, 1), (56, 1), (243, 1), (273, 1), (268, 1), (276, 1)]
10882
+
10883
+ ###################################################################################
10884
+
10885
+ SAD_MINOR = [(178, 1800), (267, 1764), (233, 1727), (309, 1671), (288, 1644), (0, 1610),
10886
+ (301, 1580), (320, 1532), (89, 1512), (317, 1454), (319, 1417), (314, 1383),
10887
+ (272, 238), (269, 232), (183, 230), (180, 224), (212, 219), (34, 217),
10888
+ (238, 217), (311, 214), (2, 212), (5, 210), (303, 208), (293, 206), (91, 202),
10889
+ (94, 202), (235, 200), (13, 199), (290, 198), (316, 192), (3, 190), (306, 188),
10890
+ (280, 187), (193, 185), (291, 184), (123, 183), (191, 182), (37, 179),
10891
+ (199, 172), (102, 169), (181, 164), (110, 163), (92, 163), (246, 161),
10892
+ (21, 157), (236, 156), (312, 154), (270, 146), (203, 146), (15, 144),
10893
+ (126, 135), (25, 135), (114, 135), (304, 132), (215, 131), (104, 131),
10894
+ (254, 130), (38, 124), (112, 124), (282, 123), (216, 114), (23, 111),
10895
+ (127, 102), (201, 101), (16, 100), (283, 96), (248, 96), (289, 92), (268, 92),
10896
+ (194, 92), (258, 91), (310, 87), (105, 86), (302, 81), (179, 77), (234, 77),
10897
+ (249, 76), (256, 76), (318, 60), (315, 57), (1, 53), (8, 49), (186, 47),
10898
+ (90, 47), (97, 47), (224, 47), (55, 46), (241, 46), (275, 46), (296, 45),
10899
+ (45, 43), (144, 42), (46, 38), (274, 37), (42, 36), (135, 36), (134, 34),
10900
+ (217, 31), (214, 30), (59, 30), (61, 30), (240, 28), (148, 28), (70, 28),
10901
+ (159, 28), (73, 27), (49, 27), (277, 26), (295, 26), (308, 26), (138, 26),
10902
+ (227, 26), (223, 25), (10, 25), (120, 25), (221, 24), (31, 24), (128, 24),
10903
+ (185, 23), (39, 23), (99, 23), (36, 23), (150, 21), (243, 21), (162, 21),
10904
+ (7, 20), (206, 18), (298, 18), (96, 18), (125, 18), (284, 16), (198, 16),
10905
+ (209, 16), (264, 16), (43, 16), (14, 15), (213, 15), (132, 15), (158, 14),
10906
+ (28, 14), (188, 13), (117, 13), (35, 13), (253, 12), (103, 12), (192, 12),
10907
+ (220, 12), (30, 12), (225, 11), (69, 11), (287, 11), (131, 11), (24, 10),
10908
+ (119, 10), (208, 10), (261, 9), (48, 9), (76, 9), (165, 9), (9, 9), (66, 9),
10909
+ (4, 9), (195, 8), (250, 8), (58, 8), (147, 8), (247, 8), (281, 8), (47, 7),
10910
+ (219, 7), (20, 7), (109, 7), (56, 7), (242, 6), (204, 6), (259, 6), (137, 6),
10911
+ (226, 6), (292, 6), (93, 6), (62, 6), (98, 6), (151, 6), (187, 5), (115, 5),
10912
+ (273, 5), (294, 5), (17, 5), (130, 5), (106, 5), (145, 5), (313, 5), (182, 5),
10913
+ (239, 5), (237, 5), (276, 4), (6, 4), (41, 4), (57, 4), (113, 4), (124, 4),
10914
+ (146, 4), (271, 4), (18, 4), (297, 3), (40, 3), (129, 3), (19, 3), (68, 3),
10915
+ (95, 3), (108, 3), (157, 3), (184, 3), (197, 3), (232, 3), (86, 3), (175, 3),
10916
+ (82, 3), (228, 3), (71, 3), (160, 3), (64, 3), (153, 3), (26, 2), (307, 2),
10917
+ (60, 2), (218, 2), (222, 2), (305, 2), (202, 2), (263, 2), (11, 2), (136, 2),
10918
+ (171, 2), (79, 2), (244, 1), (278, 1), (299, 1), (149, 1), (22, 1), (257, 1),
10919
+ (252, 1), (286, 1), (75, 1), (77, 1), (54, 1), (166, 1), (143, 1), (67, 1),
10920
+ (156, 1), (63, 1), (152, 1), (107, 1), (196, 1), (251, 1), (285, 1), (50, 1)]
10921
+
10922
+ ###################################################################################
10923
+
10924
+ UPLIFTING_MAJOR = [(267, 3776), (317, 3723), (301, 3628), (320, 3603), (178, 3569), (89, 3448),
10925
+ (309, 3337), (314, 3216), (0, 3180), (288, 3159), (233, 3061), (319, 3008),
10926
+ (112, 981), (194, 917), (256, 916), (16, 874), (216, 843), (283, 835),
10927
+ (201, 783), (105, 771), (127, 766), (23, 715), (38, 692), (249, 637),
10928
+ (272, 459), (191, 448), (91, 437), (235, 437), (306, 423), (303, 404),
10929
+ (280, 400), (13, 396), (183, 394), (269, 394), (94, 393), (102, 389),
10930
+ (180, 386), (293, 371), (181, 370), (5, 358), (290, 348), (212, 342),
10931
+ (238, 335), (246, 324), (270, 315), (92, 314), (3, 310), (254, 308),
10932
+ (316, 301), (110, 295), (123, 291), (2, 285), (104, 268), (236, 255),
10933
+ (304, 254), (311, 250), (34, 250), (193, 244), (291, 244), (199, 235),
10934
+ (312, 232), (114, 219), (215, 216), (248, 205), (37, 201), (25, 201),
10935
+ (15, 197), (126, 195), (282, 191), (21, 184), (258, 167), (268, 151),
10936
+ (179, 148), (203, 142), (234, 128), (90, 123), (1, 119), (144, 116),
10937
+ (289, 102), (302, 99), (228, 97), (310, 95), (318, 94), (119, 92), (159, 91),
10938
+ (285, 89), (139, 85), (162, 83), (50, 81), (73, 78), (42, 78), (196, 77),
10939
+ (30, 76), (131, 75), (251, 75), (220, 73), (39, 72), (55, 71), (45, 71),
10940
+ (315, 70), (217, 70), (120, 69), (227, 67), (264, 64), (209, 63), (31, 63),
10941
+ (134, 62), (36, 62), (273, 61), (70, 60), (43, 58), (221, 58), (8, 56),
10942
+ (160, 55), (138, 55), (192, 55), (97, 54), (186, 54), (241, 53), (71, 53),
10943
+ (49, 53), (128, 53), (132, 52), (223, 52), (298, 52), (296, 51), (275, 51),
10944
+ (208, 50), (263, 50), (99, 50), (214, 50), (277, 50), (153, 49), (96, 48),
10945
+ (148, 48), (218, 47), (14, 46), (18, 45), (103, 44), (281, 44), (150, 43),
10946
+ (125, 43), (10, 43), (247, 42), (294, 41), (64, 41), (307, 40), (40, 40),
10947
+ (129, 40), (239, 40), (7, 38), (284, 38), (243, 38), (146, 37), (6, 37),
10948
+ (95, 37), (184, 37), (213, 36), (188, 36), (35, 35), (59, 35), (124, 34),
10949
+ (107, 33), (24, 32), (17, 31), (257, 31), (147, 30), (195, 30), (202, 29),
10950
+ (308, 28), (106, 28), (57, 28), (276, 26), (115, 26), (58, 26), (61, 25),
10951
+ (9, 25), (242, 25), (113, 25), (11, 24), (204, 23), (259, 22), (46, 22),
10952
+ (274, 21), (255, 21), (135, 21), (224, 21), (240, 20), (295, 19), (187, 19),
10953
+ (250, 19), (48, 19), (297, 19), (185, 18), (26, 17), (149, 17), (98, 16),
10954
+ (261, 14), (197, 14), (286, 14), (75, 14), (164, 14), (68, 13), (157, 13),
10955
+ (173, 13), (271, 12), (137, 12), (226, 12), (44, 12), (230, 11), (109, 11),
10956
+ (117, 11), (206, 11), (292, 11), (182, 11), (222, 11), (252, 11), (244, 10),
10957
+ (278, 10), (84, 10), (305, 10), (198, 10), (237, 10), (108, 10), (60, 10),
10958
+ (53, 9), (136, 9), (158, 9), (225, 9), (69, 9), (47, 9), (287, 8), (41, 8),
10959
+ (100, 8), (189, 8), (52, 8), (141, 8), (28, 8), (219, 8), (19, 8), (93, 8),
10960
+ (133, 8), (165, 7), (313, 7), (20, 7), (76, 6), (142, 6), (231, 6), (253, 6),
10961
+ (130, 6), (151, 5), (51, 5), (140, 5), (229, 5), (168, 5), (4, 5), (299, 5),
10962
+ (22, 5), (170, 5), (155, 4), (62, 4), (145, 4), (174, 4), (66, 3), (56, 3),
10963
+ (72, 3), (54, 3), (143, 3), (154, 3), (85, 3), (77, 3), (166, 3), (67, 3),
10964
+ (152, 3), (245, 3), (279, 3), (111, 3), (200, 3), (171, 3), (79, 3), (210, 2),
10965
+ (265, 2), (74, 2), (163, 2), (65, 2), (27, 2), (116, 2), (205, 2), (260, 2),
10966
+ (32, 2), (156, 2), (63, 2), (300, 2), (12, 2), (101, 2), (190, 2), (232, 1),
10967
+ (121, 1), (81, 1), (86, 1), (175, 1), (82, 1)]
10968
+
10969
+ ###################################################################################
10970
+
10971
+ UPLIFTING_MINOR = [(301, 5035), (233, 5017), (314, 4999), (89, 4970), (320, 4956), (319, 4954),
10972
+ (0, 4793), (267, 4760), (309, 4744), (178, 4715), (317, 4697), (288, 4644),
10973
+ (114, 1184), (25, 1127), (248, 1111), (282, 1010), (193, 943), (203, 938),
10974
+ (105, 912), (104, 906), (258, 906), (280, 883), (246, 882), (283, 870),
10975
+ (16, 867), (94, 857), (127, 854), (238, 845), (102, 834), (194, 830), (5, 822),
10976
+ (306, 813), (38, 795), (183, 792), (249, 791), (13, 784), (191, 780),
10977
+ (256, 778), (112, 777), (290, 774), (23, 748), (272, 741), (235, 737),
10978
+ (269, 737), (293, 714), (215, 700), (37, 695), (201, 694), (303, 693),
10979
+ (15, 685), (316, 684), (311, 682), (216, 672), (126, 666), (91, 622), (2, 618),
10980
+ (180, 616), (254, 606), (270, 596), (304, 592), (236, 590), (181, 577),
10981
+ (92, 572), (34, 558), (123, 554), (3, 540), (21, 534), (212, 524), (312, 517),
10982
+ (110, 508), (199, 500), (291, 491), (128, 224), (243, 217), (298, 217),
10983
+ (144, 214), (90, 214), (39, 210), (8, 207), (162, 206), (234, 205), (97, 204),
10984
+ (186, 204), (241, 203), (217, 200), (268, 199), (10, 198), (1, 192), (55, 190),
10985
+ (179, 190), (188, 187), (125, 184), (315, 184), (302, 182), (318, 180),
10986
+ (275, 178), (296, 168), (289, 168), (277, 166), (73, 166), (36, 165),
10987
+ (119, 162), (263, 161), (99, 160), (310, 160), (30, 157), (214, 135),
10988
+ (138, 135), (264, 133), (159, 129), (134, 128), (131, 127), (227, 125),
10989
+ (70, 125), (281, 122), (43, 120), (46, 119), (209, 118), (247, 117),
10990
+ (132, 116), (120, 110), (221, 108), (208, 108), (31, 106), (45, 103), (49, 99),
10991
+ (224, 96), (96, 95), (59, 94), (220, 91), (148, 90), (135, 90), (7, 88),
10992
+ (273, 88), (147, 84), (239, 82), (274, 77), (307, 76), (294, 75), (223, 75),
10993
+ (240, 73), (17, 73), (106, 73), (192, 72), (213, 71), (185, 71), (58, 71),
10994
+ (24, 71), (139, 70), (103, 66), (9, 66), (276, 65), (42, 65), (129, 64),
10995
+ (95, 64), (187, 63), (242, 60), (98, 60), (150, 59), (285, 58), (40, 57),
10996
+ (261, 57), (184, 57), (218, 56), (50, 55), (195, 55), (284, 53), (48, 52),
10997
+ (196, 52), (117, 52), (251, 50), (295, 49), (202, 49), (250, 49), (146, 48),
10998
+ (259, 48), (228, 48), (206, 48), (14, 48), (57, 47), (35, 47), (61, 46),
10999
+ (6, 45), (113, 45), (124, 43), (157, 42), (28, 42), (137, 41), (68, 41),
11000
+ (297, 40), (308, 40), (257, 39), (115, 38), (158, 38), (107, 37), (204, 35),
11001
+ (160, 35), (71, 33), (26, 32), (226, 31), (69, 31), (153, 30), (165, 27),
11002
+ (64, 27), (287, 26), (136, 25), (109, 25), (225, 24), (164, 24), (76, 24),
11003
+ (286, 23), (75, 23), (155, 23), (11, 22), (252, 22), (253, 22), (93, 22),
11004
+ (271, 22), (47, 21), (108, 21), (41, 21), (198, 20), (197, 19), (237, 19),
11005
+ (219, 19), (182, 18), (66, 18), (130, 17), (292, 17), (305, 17), (20, 16),
11006
+ (145, 15), (4, 15), (18, 15), (255, 14), (100, 14), (189, 14), (62, 14),
11007
+ (244, 13), (151, 13), (170, 12), (52, 11), (141, 11), (278, 10), (313, 10),
11008
+ (56, 10), (149, 9), (133, 9), (84, 8), (173, 8), (60, 8), (200, 8), (65, 7),
11009
+ (299, 7), (230, 7), (44, 7), (154, 6), (85, 6), (222, 6), (174, 5), (81, 5),
11010
+ (111, 5), (163, 4), (27, 4), (116, 4), (205, 4), (19, 4), (22, 4), (210, 3),
11011
+ (265, 3), (74, 3), (168, 3), (51, 3), (260, 3), (12, 2), (101, 2), (190, 2),
11012
+ (245, 2), (279, 2), (142, 2), (231, 2), (175, 2), (82, 2), (171, 2), (79, 2),
11013
+ (152, 1), (140, 1), (229, 1), (54, 1), (143, 1), (53, 1), (121, 1), (300, 1),
11014
+ (262, 1), (72, 1), (161, 1), (29, 1), (118, 1), (207, 1)]
11015
+
11016
+ ###################################################################################
11017
+
11018
+ ALL_MOOD_TYPES = [HAPPY_MAJOR,
11019
+ UPLIFTING_MAJOR,
11020
+ UPLIFTING_MINOR,
11021
+ NEUTRAL_MAJOR,
11022
+ NEUTRAL_MINOR,
11023
+ MELANCHOLIC_MAJOR,
11024
+ MELANCHOLIC_MINOR,
11025
+ SAD_MAJOR,
11026
+ SAD_MINOR
11027
+ ]
11028
+
11029
+ ###################################################################################
11030
+
11031
+ ALL_MOOD_TYPES_LABELS = ['Happy Major',
11032
+ 'Uplifting Major',
11033
+ 'Uplifting Minor',
11034
+ 'Neutral Major',
11035
+ 'Neutral Minor',
11036
+ 'Melancholic Major',
11037
+ 'Melancholic Minor',
11038
+ 'Sad Major',
11039
+ 'Sad Minor'
11040
+ ]
11041
+
11042
+ ###################################################################################
11043
+
11044
+ LEAD_INSTRUMENTS = [0, 1, 2, 3, 4, 5, 6, 7, # Piano
11045
+ 8, 9, 10, 11, 12, 13, 14, 15, # Chromatic Percussion
11046
+ 16, 17, 18, 19, 20, 21, 22, 23, # Organ
11047
+ 24, 25, 26, 27, 28, 29, 30, 31, # Guitar
11048
+ 40, 41, 46, # Strings
11049
+ 52, 53, 54, # Ensemble
11050
+ 56, 57, 59, 60, # Brass
11051
+ 64, 65, 66, 67, 68, 69, 70, 71, # Reed
11052
+ 72, 73, 74, 75, 76, 77, 78, 79, # Pipe
11053
+ 80, 81, 87 # Synth Lead
11054
+ ]
11055
+
11056
+ ###################################################################################
11057
+
11058
+ BASE_INSTRUMENTS = [32, 33, 34, 35, 36, 37, 38, 39, # Bass
11059
+ 42, 43, # Strings
11060
+ 58, 61, 62, 63, # Brass
11061
+ 87 # Synth Lead
11062
+ ]
11063
+
11064
+ ###################################################################################
11065
+
11066
+ def escore_notes_pitches_range(escore_notes,
11067
+ range_patch=-1,
11068
+ pitches_idx=4,
11069
+ patches_idx=6
11070
+ ):
11071
+
11072
+ pitches = []
11073
+
11074
+ if -1 < range_patch < 129:
11075
+ pitches = [e[pitches_idx] for e in escore_notes if e[patches_idx] == range_patch]
11076
+
11077
+ else:
11078
+ pitches = [e[pitches_idx] for e in escore_notes]
11079
+
11080
+ if pitches:
11081
+ min_pitch = min(pitches)
11082
+ avg_pitch = sum(pitches) / len(pitches)
11083
+ mode_pitch = statistics.mode(pitches)
11084
+ max_pitch = max(pitches)
11085
+
11086
+ return [max_pitch-min_pitch, min_pitch, max_pitch, avg_pitch, mode_pitch]
11087
+
11088
+ else:
11089
+ return [ -1] * 6
11090
+
11091
  ###################################################################################
11092
  #
11093
  # This is the end of the TMIDI X Python module