1 | commit 04a1f6e01876eaee762033ca2f9ed372d8d99c2d |
2 | Author: acidvegas <acid.vegas@acid.vegas> |
3 | Date: Sat Jul 13 18:52:23 2019 -0400 |
4 | |
5 | Initial commit |
6 | --- |
7 | LICENSE | 15 ++++++ |
8 | README.md | 0 |
9 | mzk/constants.py | 78 ++++++++++++++++++++++++++++ |
10 | mzk/functions.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
11 | mzk/main.py | 6 +++ |
12 | 5 files changed, 252 insertions(+) |
13 | |
14 | diff --git a/LICENSE b/LICENSE |
15 | new file mode 100644 |
16 | index 0000000..69997e8 |
17 | --- /dev/null |
18 | +++ b/LICENSE |
19 | @@ -0,0 +1,15 @@ |
20 | +ISC License |
21 | + |
22 | +Copyright (c) 2019, acidvegas <acid.vegas@acid.vegas> |
23 | + |
24 | +Permission to use, copy, modify, and/or distribute this software for any |
25 | +purpose with or without fee is hereby granted, provided that the above |
26 | +copyright notice and this permission notice appear in all copies. |
27 | + |
28 | +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
29 | +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
30 | +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
31 | +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
32 | +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
33 | +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
34 | +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
35 | diff --git a/README.md b/README.md |
36 | new file mode 100644 |
37 | index 0000000..e69de29 |
38 | diff --git a/mzk/constants.py b/mzk/constants.py |
39 | new file mode 100644 |
40 | index 0000000..670489d |
41 | --- /dev/null |
42 | +++ b/mzk/constants.py |
43 | @@ -0,0 +1,78 @@ |
44 | +#!/usr/bin/env python |
45 | +# mzk music theory helper - developed by acidvegas in python (https://acid.vegas/mzk) |
46 | +# constants.py |
47 | + |
48 | +circle = ''' major |
49 | + |
50 | + C |
51 | + F G |
52 | + ♮ |
53 | + 1♭ 1♯ |
54 | + a |
55 | + B♭ d c D |
56 | + 2♭ 2♯ |
57 | + g minor b |
58 | + |
59 | + |
60 | + E♭ 3♭ c f♯ 3♯ A |
61 | + |
62 | + |
63 | + f c♯ |
64 | + 4♭ 4 |
65 | + A♭ b♭ g♯ E |
66 | + e♭/d♯ |
67 | + 5♭/7♯ 7♭/5♯ |
68 | + 6♭/6♯ |
69 | + D♭ B |
70 | + G♭/F♯ |
71 | + C♯ C♭''' |
72 | + |
73 | +colors = { |
74 | + 'gray' : '\033[0;90m', |
75 | + 'red' : '\033[0;91m', |
76 | + 'green' : '\033[0;92m', |
77 | + 'reset' : '\033[0m' |
78 | +} |
79 | + |
80 | +intervals = { |
81 | + 'unison' : {'semitones':0, 'short_name':'P1' }, |
82 | + 'minor_second' : {'semitones':1, 'short_name':'m2' }, |
83 | + 'major_second' : {'semitones':2, 'short_name':'M2' }, |
84 | + 'minor_third' : {'semitones':3, 'short_name':'m3' }, |
85 | + 'major_third' : {'semitones':4, 'short_name':'M3' }, |
86 | + 'perfect_fourth' : {'semitones':5, 'short_name':'P4' }, |
87 | + 'augmented_fourth' : {'semitones':6, 'short_name':'+4' }, |
88 | + 'diminished_fifth' : {'semitones':6, 'short_name':'d5' }, |
89 | + 'perfect_fifth' : {'semitones':7, 'short_name':'P5' }, |
90 | + 'minor_sixth' : {'semitones':8, 'short_name':'m6' }, |
91 | + 'major_sixth' : {'semitones':9, 'short_name':'M6' }, |
92 | + 'minor_seventh' : {'semitones':10, 'short_name':'m7' }, |
93 | + 'major_seventh' : {'semitones':11, 'short_name':'M7' }, |
94 | + 'perfect_octave' : {'semitones':12, 'short_name':'8va'} |
95 | +} |
96 | + |
97 | +notes = ('A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#' ) |
98 | +numerals = ('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII' ) |
99 | +scale_degrees = ('tonic','supertonic','mediant','subdominant','dominant''submediant','subtonic') |
100 | + |
101 | +scales = { |
102 | + 'algerian' : '2131131', |
103 | + 'aeolian' : '2122122', |
104 | + 'blues' : '321132', |
105 | + 'chromatic' : '1111111', |
106 | + 'dorian' : '2122212', |
107 | + 'half_whole_diminished' : '12121212', |
108 | + 'harmonic_minor' : '2122131', |
109 | + 'ionian' : '2212221', |
110 | + 'locrian' : '1221222', |
111 | + 'lydian' : '2221221', |
112 | + 'major' : '2212221', |
113 | + 'major_pentatonic' : '22323', |
114 | + 'melodic_minor' : '2122221', |
115 | + 'mixolydian' : '2212212', |
116 | + 'natural_minor' : '2122122', |
117 | + 'persian' : '1311231', |
118 | + 'phrygian' : '1222122', |
119 | + 'whole_half_diminished' : '21212121', |
120 | + 'whole_tone' : '2222222' |
121 | +} |
122 | diff --git a/mzk/functions.py b/mzk/functions.py |
123 | new file mode 100644 |
124 | index 0000000..b3cf09a |
125 | --- /dev/null |
126 | +++ b/mzk/functions.py |
127 | @@ -0,0 +1,153 @@ |
128 | +#!/usr/bin/env python |
129 | +# mzk music theory helper - developed by acidvegas in python (https://acid.vegas/mzk) |
130 | +# functions.py |
131 | + |
132 | +import constants |
133 | + |
134 | +def generate_notes(key): |
135 | + notes = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#'] |
136 | + while notes[0] != key: |
137 | + notes.append(notes.pop(0)) |
138 | + return notes |
139 | + |
140 | +def generate_scale(string, scale_notes, full=False): |
141 | + notes = generate_notes(string.upper())*2 if full else generate_notes(string.upper()) |
142 | + notes.append(notes[0]) # add root note to the end |
143 | + for index,note in enumerate(notes): |
144 | + if note in scale_notes: |
145 | + notes[index] = notes[index].center(5, '-') |
146 | + else: |
147 | + notes[index] = '-'*5 |
148 | + return notes |
149 | + |
150 | +def get_pattern(pattern): |
151 | + new_pattern = list() |
152 | + for step in pattern: |
153 | + if step == '1' : new_pattern.append('H') |
154 | + elif step == '2' : new_pattern.append('W') |
155 | + elif step == '3' : new_pattern.append('WH') |
156 | + return ' '.join(new_pattern) |
157 | + |
158 | +def scale(type, key): |
159 | + last = 0 |
160 | + notes = generate_notes(key) |
161 | + scale_notes = [notes[0],] |
162 | + for step in scales[type]: |
163 | + last += int(step) |
164 | + if last >= len(notes): |
165 | + last -= len(notes) |
166 | + scale_notes.append(notes[last]) |
167 | + return scale_notes |
168 | + |
169 | +def print_chord(): |
170 | + # todo: finish this |
171 | + print('◯ ⬤ ') |
172 | + print('''╳ ╳ ╳ ╳ ╳ ╳ |
173 | +┌───┬───┬───┬───┬───┐ |
174 | +│ │ │ │ │ │ |
175 | +├───┼───┼───┼───┼───┤ |
176 | +│ │ │ │ │ │ |
177 | +├───┼───┼───┼───┼───┤ |
178 | +│ │ │ │ │ │ |
179 | +├───┼───┼───┼───┼───┤ |
180 | +│ │ │ │ │ │ |
181 | +├───┼───┼───┼───┼───┤ |
182 | +│ │ │ │ │ │ |
183 | +└───┴───┴───┴───┴───┘ |
184 | +E A D G B e''') |
185 | + |
186 | +def print_circle_of_fifths(): |
187 | + ''' |
188 | + definition: |
189 | + the relationship among the 12 tones of the chromatic scale, their corresponding key signatures, & the associated major/minor keys |
190 | + |
191 | + accidentals: |
192 | + sharps - F, C, G, D, A, E, B |
193 | + flats - B, E, A, D, G, C, F |
194 | + |
195 | + intervals: |
196 | + unison |
197 | + perfect fifth |
198 | + major sencond |
199 | + major sixth |
200 | + major third |
201 | + major seventh |
202 | + augmented fourth |
203 | + minor second |
204 | + minor sixth |
205 | + minor third |
206 | + minor seventh |
207 | + perfect fourth |
208 | + ''' |
209 | + circle = constants.circle.replace('\n',' \n') + ' ' # todo: fix this |
210 | + for note in ('major','C','F','B♭','E♭','A♭','D♭','C♯','G♭/F♯','B','C♭','E','A','D','G'): # todo: reverse |
211 | + circle = circle.replace(f' {note} ', f' \033[91m{note}\033[0m ') |
212 | + for item in ('♮','1♭','2♭','3♭','4♭','5♭/7♯','6♭/6♯','7♭/5♯','4','3♯','2♯','1♯'): |
213 | + circle = circle.replace(f' {item} ', f' \033[90m{item}\033[0m ') |
214 | + for note in ('minor','a','d','g','c','f','b♭','e♭/d♯','g♯','c♯','f♯','b','c'): |
215 | + circle = circle.replace(f' {note} ', f' \033[92m{note}\033[0m ') |
216 | + print(circle) |
217 | + #print(print_circle_of_fifths.__doc__) |
218 | + |
219 | +def print_intervals(): |
220 | + ''' |
221 | + definition: |
222 | + the distance between two notes or pitches |
223 | + |
224 | + note: |
225 | + semitone - half step |
226 | + tone - whole step (b to c & e to f is a tone) |
227 | + |
228 | + types: |
229 | + harmonic interval - notes played simultaneously |
230 | + melodic interval - notes played successively |
231 | + |
232 | + makeup: |
233 | + quantity - distance between two notes |
234 | + quality - number of semitones between notes |
235 | + |
236 | + qualities: |
237 | + major/minor - 2nds, 3rds, 6ths, 7ths |
238 | + perfect - 4ths, 5ths, octaves |
239 | + diminished - minor/perfect - 1 semitone |
240 | + augmented - major/perfect + 1 semitone |
241 | + ''' |
242 | + print(' I N T E R V A L S ') |
243 | + print('┌───────────┬──────────────────┬───────┐') |
244 | + print('│ semitones │ quality │ short │') |
245 | + print('├───────────┼──────────────────┼───────┤') |
246 | + for interval, info in constants.intervals.items(): |
247 | + print('│ {0} │ {1} │ {2} │'.format(str(info['semitones']).rjust(9), interval.ljust(16), info['short_name'].ljust(5))) |
248 | + print('└───────────┴──────────────────┴───────┘') |
249 | + #print(print_intervals.__doc__) |
250 | + |
251 | +def print_scale(root, type, full=False): |
252 | + frets = (24,147) if full else (12,75) |
253 | + print(f'{root.upper()} {type.upper()} SCALE'.center(frets[1])) |
254 | + print(' ┌' + '┬'.join('─'*5 for x in range(frets[0])) + '┐') |
255 | + print('0 │' + '│'.join(str(x).center(5) for x in range(1,frets[0]+1)) + '│') |
256 | + print(' ├' + '┼'.join('─'*5 for x in range(frets[0])) + '┤') |
257 | + scale_notes = scale(type, root) |
258 | + for string in ('eBGDAE'): |
259 | + string_notes = generate_scale(string, scale_notes, full) |
260 | + print(string + ' │' + '│'.join(note.center(5, '-') for note in string_notes[1:]) + '│') |
261 | + print(' └' + '┴'.join('─'*5 for x in range(frets[0])) + '┘') |
262 | + print((', '.join(scale_notes) + ' / ' + get_pattern(scales[type])).rjust(frets[1])) |
263 | + |
264 | +def print_scales(): |
265 | + ''' |
266 | + definition: |
267 | + any set of musical notes ordered by fundamental frequency or pitch |
268 | + |
269 | + note: |
270 | + 1 - half step |
271 | + 2 - whole step |
272 | + 3 - whole step half step''' |
273 | + print(' S C A L E S ') |
274 | + print('┌───────────────────────┬─────────────────┐') |
275 | + print('│ name │ intervals │') |
276 | + print('├───────────────────────┼─────────────────┤') |
277 | + for name, pattern in constants.scales.items(): |
278 | + print(f'│ {name.ljust(21)} │ {get_pattern(pattern).rjust(15)} │') |
279 | + print('└───────────────────────┴─────────────────┘') |
280 | + #print(print_scales.__doc__) |
281 | diff --git a/mzk/main.py b/mzk/main.py |
282 | new file mode 100644 |
283 | index 0000000..ab013d2 |
284 | --- /dev/null |
285 | +++ b/mzk/main.py |
286 | @@ -0,0 +1,6 @@ |
287 | +#!/usr/bin/env python |
288 | +# mzk music theory helper - developed by acidvegas in python (https://acid.vegas/mzk) |
289 | +# main.py |
290 | + |
291 | +import argparser |
292 | +import sys |