←︎ mzk :: 04a1f6e


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