Advertisement
Guest User

Untitled

a guest
May 24th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.42 KB | None | 0 0
  1. # slonimsky.py
  2. """
  3. Find by brute force four triads (major, minor, augmented, disminished) that comprends the 12 notes.
  4. TODO:
  5. * Fix enharmonic names
  6. * Replace brute force and random tries by some musical logic ;-)
  7. """
  8. import random
  9.  
  10. notes = {
  11.             60: {'flat': 'C', 'sharp': 'B#', 'name': 'C'},
  12.             61: {'flat': 'Db', 'sharp': 'C#'},
  13.             62: {'flat': 'D', 'sharp': 'D', 'name': 'D'},
  14.             63: {'flat': 'Eb', 'sharp': 'D#'},
  15.             64: {'flat': 'Fb', 'sharp': 'E', 'name': 'E'},
  16.             65: {'flat': 'F', 'sharp': 'E#', 'name': 'F'},
  17.             66: {'flat': 'Gb', 'sharp': 'F#'},
  18.             67: {'flat': 'G', 'sharp': 'F##', 'name': 'G'},
  19.             68: {'flat': 'Ab', 'sharp': 'G#'},
  20.             69: {'flat': 'A', 'sharp': 'A', 'name': 'A'},
  21.             70: {'flat': 'Bb', 'sharp': 'A#'},
  22.             71: {'flat': 'Cb', 'sharp': 'B', 'name': 'B'}
  23.         }
  24.  
  25. def is_third(high_note, low_note):
  26.     ord1 = ord(low_note.replace('b', '').replace('#', ''))
  27.     ord2 = ord(high_note.replace('b', '').replace('#', ''))
  28.     if ord2 < ord1: # Ex: E -> A (ord('A') is below ord('E'))
  29.         ord2 += 7
  30.     ret = ord2 - ord1 == 2
  31.     return ret
  32.  
  33. def change_note_name(note, detected_note_name):
  34.     """
  35.    Change the enarmonic name.
  36.    Ex: change_note_name(61, 'Db') returns 'C#'
  37.    # Some bugs/improvements:
  38.    # B augmented triad: augmented fith mispelled (it should be F##) ['B', 'D#', 'G']
  39.    # Db minor triad: minor third mispelled (it should be Fb) ['Db', 'E', 'G#']
  40.    """
  41.     data_name = notes[note]
  42.     if 'b' in detected_note_name:
  43.         return data_name['sharp']
  44.     elif '#' in detected_note_name:
  45.         return data_name['flat']
  46.     else:
  47.         return detected_note_name
  48.  
  49. def name_to_note(note_name):
  50.     for k, v in notes.items():
  51.         if note_name == v['flat'] or note_name == v['sharp'] or ('name' in v and note_name == v['name']):
  52.             return k
  53.     return -1
  54.  
  55. def note_to_name(note, previous_note_name=None):
  56.     note_name = notes[note]['flat']
  57.     if 'name' in notes[note]:
  58.         note_name = notes[note]['name']
  59.     if previous_note_name and not is_third(note_name, previous_note_name):
  60.         note_name = change_note_name(note, note_name)
  61.     return note_name
  62.  
  63. def translate_triad(triad):
  64.     ret = []
  65.     previous_note_name = None
  66.     for note in triad:
  67.         if note > 71:
  68.             note = note - 12
  69.         name = note_to_name(note, previous_note_name)
  70.         previous_note_name = name
  71.         ret.append(name)
  72.     return ret
  73.  
  74.  
  75. def make_triad(root, type):
  76.     ret = []
  77.     if type == 'major':
  78.         ret = [root, root + 4, root + 7]
  79.     elif type == 'minor':
  80.         ret = [root, root + 3, root + 7]
  81.     elif type == 'disminished':
  82.         ret = [root, root + 3, root + 6]
  83.     elif type == 'augmented':
  84.         ret = [root, root + 4, root + 8]
  85.    
  86.     return {'name': note_to_name(root)+ ' ' +type, 'notes': translate_triad(ret)}
  87.  
  88.  
  89. def get_triads():
  90.     types = ['major', 'minor', 'disminished', 'augmented']
  91.     roots = notes.keys()
  92.  
  93.     notes_found = []
  94.     triads_found = []
  95.     used_elements = []
  96.  
  97.     while len(triads_found) < 4:
  98.         root = random.choice(roots)
  99.         triad = random.choice(types)
  100.         key = triad + str(root)
  101.         if key in used_elements:
  102.             continue
  103.         used_elements.append(key)
  104.         triad_data = make_triad(root, triad)
  105.         triad = triad_data['notes']
  106.         n1 = name_to_note(triad[0])
  107.         n2 = name_to_note(triad[1])
  108.         n3 = name_to_note(triad[2])
  109.        
  110.         if not n1 in notes_found and not n2 in notes_found and not n3 in notes_found:
  111.            notes_found.append(n1)
  112.            notes_found.append(n2)
  113.            notes_found.append(n3)
  114.            triads_found.append(triad_data)
  115.            notes_found.sort()
  116.  
  117.         if len(used_elements) == len(types) * len(roots):
  118.             return []
  119.  
  120.     triads_found.sort()
  121.     return triads_found
  122.  
  123. def main(how_many=10):
  124.     all_triads = []
  125.     triads = get_triads()
  126.     while True:
  127.         if (len(triads) > 0) and triads not in all_triads:
  128.             all_triads.append(triads)
  129.         triads = get_triads()
  130.         if len(all_triads) > how_many:
  131.             break
  132.     all_triads.sort()
  133.     return all_triads
  134.  
  135.  
  136. if __name__ == '__main__':
  137.     all_triads = main(250)
  138.     for at in all_triads:
  139.         for t in at:
  140.             print t['name'], '=>', t['notes'],
  141.         print
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement