Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # slonimsky.py
- """
- Find by brute force four triads (major, minor, augmented, disminished) that comprends the 12 notes.
- TODO:
- * Fix enharmonic names
- * Replace brute force and random tries by some musical logic ;-)
- """
- import random
- notes = {
- 60: {'flat': 'C', 'sharp': 'B#', 'name': 'C'},
- 61: {'flat': 'Db', 'sharp': 'C#'},
- 62: {'flat': 'D', 'sharp': 'D', 'name': 'D'},
- 63: {'flat': 'Eb', 'sharp': 'D#'},
- 64: {'flat': 'Fb', 'sharp': 'E', 'name': 'E'},
- 65: {'flat': 'F', 'sharp': 'E#', 'name': 'F'},
- 66: {'flat': 'Gb', 'sharp': 'F#'},
- 67: {'flat': 'G', 'sharp': 'F##', 'name': 'G'},
- 68: {'flat': 'Ab', 'sharp': 'G#'},
- 69: {'flat': 'A', 'sharp': 'A', 'name': 'A'},
- 70: {'flat': 'Bb', 'sharp': 'A#'},
- 71: {'flat': 'Cb', 'sharp': 'B', 'name': 'B'}
- }
- def is_third(high_note, low_note):
- ord1 = ord(low_note.replace('b', '').replace('#', ''))
- ord2 = ord(high_note.replace('b', '').replace('#', ''))
- if ord2 < ord1: # Ex: E -> A (ord('A') is below ord('E'))
- ord2 += 7
- ret = ord2 - ord1 == 2
- return ret
- def change_note_name(note, detected_note_name):
- """
- Change the enarmonic name.
- Ex: change_note_name(61, 'Db') returns 'C#'
- # Some bugs/improvements:
- # B augmented triad: augmented fith mispelled (it should be F##) ['B', 'D#', 'G']
- # Db minor triad: minor third mispelled (it should be Fb) ['Db', 'E', 'G#']
- """
- data_name = notes[note]
- if 'b' in detected_note_name:
- return data_name['sharp']
- elif '#' in detected_note_name:
- return data_name['flat']
- else:
- return detected_note_name
- def name_to_note(note_name):
- for k, v in notes.items():
- if note_name == v['flat'] or note_name == v['sharp'] or ('name' in v and note_name == v['name']):
- return k
- return -1
- def note_to_name(note, previous_note_name=None):
- note_name = notes[note]['flat']
- if 'name' in notes[note]:
- note_name = notes[note]['name']
- if previous_note_name and not is_third(note_name, previous_note_name):
- note_name = change_note_name(note, note_name)
- return note_name
- def translate_triad(triad):
- ret = []
- previous_note_name = None
- for note in triad:
- if note > 71:
- note = note - 12
- name = note_to_name(note, previous_note_name)
- previous_note_name = name
- ret.append(name)
- return ret
- def make_triad(root, type):
- ret = []
- if type == 'major':
- ret = [root, root + 4, root + 7]
- elif type == 'minor':
- ret = [root, root + 3, root + 7]
- elif type == 'disminished':
- ret = [root, root + 3, root + 6]
- elif type == 'augmented':
- ret = [root, root + 4, root + 8]
- return {'name': note_to_name(root)+ ' ' +type, 'notes': translate_triad(ret)}
- def get_triads():
- types = ['major', 'minor', 'disminished', 'augmented']
- roots = notes.keys()
- notes_found = []
- triads_found = []
- used_elements = []
- while len(triads_found) < 4:
- root = random.choice(roots)
- triad = random.choice(types)
- key = triad + str(root)
- if key in used_elements:
- continue
- used_elements.append(key)
- triad_data = make_triad(root, triad)
- triad = triad_data['notes']
- n1 = name_to_note(triad[0])
- n2 = name_to_note(triad[1])
- n3 = name_to_note(triad[2])
- if not n1 in notes_found and not n2 in notes_found and not n3 in notes_found:
- notes_found.append(n1)
- notes_found.append(n2)
- notes_found.append(n3)
- triads_found.append(triad_data)
- notes_found.sort()
- if len(used_elements) == len(types) * len(roots):
- return []
- triads_found.sort()
- return triads_found
- def main(how_many=10):
- all_triads = []
- triads = get_triads()
- while True:
- if (len(triads) > 0) and triads not in all_triads:
- all_triads.append(triads)
- triads = get_triads()
- if len(all_triads) > how_many:
- break
- all_triads.sort()
- return all_triads
- if __name__ == '__main__':
- all_triads = main(250)
- for at in all_triads:
- for t in at:
- print t['name'], '=>', t['notes'],
- print
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement