random/scales.py

89 lines
3.1 KiB
Python

#!/usr/bin/env python
# guitar scales generator - developed by acidvegas in python (https://acid.vegas/random)
scales = {
'algerian' : '2131131', # 1 = Half-step | 2 = Whole-step | 3 = Whole-step-Half-step
'aeolian' : '2122122',
'blues' : '321132',
'chromatic' : '1111111',
'dorian' : '2122212',
'half_whole_diminished' : '12121212',
'harmonic_minor' : '2122131',
'ionian' : '2212221',
'locrian' : '1221222',
'lydian' : '2221221',
'major' : '2212221',
'major_pentatonic' : '22323',
'melodic_minor' : '2122221',
'mixolydian' : '2212212',
'natural_minor' : '2122122',
'persian' : '1311231',
'phrygian' : '1222122',
'whole_half_diminished' : '21212121',
'whole_tone' : '2222222'
}
def generate_notes(key):
notes = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#']
while notes[0] != key:
notes.append(notes.pop(0))
return notes
def generate_scale(string, scale_notes, full=False):
notes = generate_notes(string.upper())*2 if full else generate_notes(string.upper())
notes.append(notes[0])
for index,note in enumerate(notes):
if note in scale_notes:
notes[index] = notes[index].center(5, '-')
else:
notes[index] = '-'*5
return notes
def get_pattern(pattern):
new_pattern = list()
for step in pattern:
if step == '1' : new_pattern.append('H')
elif step == '2' : new_pattern.append('W')
elif step == '3' : new_pattern.append('WH')
return ' '.join(new_pattern)
def scale(type, key):
last = 0
notes = generate_notes(key)
scale_notes = [notes[0],]
for step in scales[type]:
last += int(step)
if last >= len(notes):
last -= len(notes)
scale_notes.append(notes[last])
return scale_notes
def print_scale(root, type, full=False):
if root.upper() not in ('A','A#','B','C','C#','D','D#','E','F','F#','G','G#'):
raise SystemExit('invalid root note')
elif type.lower() not in scales:
raise SystemExit('invalid scale type')
else:
frets = (24,147) if full else (12,75)
print(f'{root.upper()} {type.upper()} SCALE'.center(frets[1]))
print('' + ''.join(''*5 for x in range(frets[0])) + '')
print('0 │' + ''.join(str(x).center(5) for x in range(1,frets[0]+1)) + '')
print('' + ''.join(''*5 for x in range(frets[0])) + '')
scale_notes = scale(type, root)
for string in ('eBGDAE'):
string_notes = generate_scale(string, scale_notes, full)
print(string + '' + ''.join(note.center(5, '-') for note in string_notes[1:]) + '')
print('' + ''.join(''*5 for x in range(frets[0])) + '')
print((', '.join(scale_notes) + ' / ' + get_pattern(scales[type])).rjust(frets[1]))
def print_scales():
max_key = max(len(x) for x in scales)
max_value = max(len(get_pattern(scales[x])) for x in scales)
print('NAME'.ljust(max_key+3) + 'PATTERN'.rjust(max_value))
for name, pattern in scales.items():
print(name.ljust(max_key) + '' + get_pattern(pattern).rjust(max_value))
# Main
print_scales()
print_scale('F#','major')