5 changed files with 203 additions and 16 deletions
-
19Fingering.py
-
26assets.py
-
84convert.py
-
24main.py
-
66scale.py
@ -0,0 +1,19 @@ |
|||||
|
import convert |
||||
|
|
||||
|
from math import log |
||||
|
def tune_harm(a_c,n): |
||||
|
'''Function that gives the tuning of a harmonic in relation to it's |
||||
|
nearest equal temperment note.''' |
||||
|
log_harm = a_c+12*log(n,2) |
||||
|
equal_temp = round(log_harm) |
||||
|
return (equal_temp,round(100*(log_harm-equal_temp))) |
||||
|
|
||||
|
def fingers(n,ff): |
||||
|
c = int(2**((n-ff)/12)) |
||||
|
if c <= 0: |
||||
|
c = 1 |
||||
|
while True: |
||||
|
current = tune_harm(ff,c) |
||||
|
if current[0] >= n and abs(current[1]) <= 14: |
||||
|
return current[0]-n |
||||
|
c += 1 |
||||
@ -0,0 +1,26 @@ |
|||||
|
inotes = {"C":0,"D":2,"E":4,"F":5,"G":7,"A":9,"B":11} |
||||
|
notes= {v: k for k, v in inotes.items()} |
||||
|
sign = {'#':1,'♭':-1} |
||||
|
minimal = {1: (2,), |
||||
|
2: (1,), |
||||
|
3: (3,), |
||||
|
4: (2, 3), |
||||
|
5: (4,), |
||||
|
6: (2, 4), |
||||
|
7: (1, 4), |
||||
|
8: (3, 4), |
||||
|
9: (2, 3, 4), |
||||
|
10: (1, 3, 4), |
||||
|
11: (1, 2, 3, 4)} |
||||
|
|
||||
|
everything = {1: [(2,)], |
||||
|
2: [(1,)], |
||||
|
3: [(3,), (1, 2)], |
||||
|
4: [(2, 3)], |
||||
|
5: [(4,), (1, 3)], |
||||
|
6: [(2, 4), (1, 2, 3)], |
||||
|
7: [(1, 4)], |
||||
|
8: [(3, 4), (1, 2, 4)], |
||||
|
9: [(2, 3, 4)], |
||||
|
10: [(1, 3, 4)], |
||||
|
11: [(1, 2, 3, 4)]} |
||||
@ -1,2 +1,82 @@ |
|||||
def above_c(n): |
|
||||
return 'go fuck yourself' |
|
||||
|
import re |
||||
|
from assets import notes,inotes,sign |
||||
|
from math import log |
||||
|
pat = r'(?P<note>[a-gA-G]{1})(?P<mod>[♭#]*)(?P<octave>\d*)' |
||||
|
pat = re.compile(pat) |
||||
|
tuning_a = 440 |
||||
|
|
||||
|
def num_note(n): |
||||
|
rpat = r'[^A-Ga-g#♭\d]' |
||||
|
n = re.sub(rpat,'',n).upper() |
||||
|
n = pat.match(n).groupdict() |
||||
|
note = inotes[n['note']] |
||||
|
mod = n['mod'] |
||||
|
octave = n['octave'] |
||||
|
if octave: |
||||
|
octave = int(octave) |
||||
|
else: |
||||
|
octave = 0 |
||||
|
if mod: |
||||
|
change = sign[mod[0]]*len(mod) |
||||
|
else: |
||||
|
change = 0 |
||||
|
return 12*octave+change+note |
||||
|
|
||||
|
def simple_note_name(n,notation = 'flats'): |
||||
|
if notation not in ('sharps','flats'): |
||||
|
raise ValueError('Notation flag is either "sharps" or "flats."') |
||||
|
|
||||
|
octave = str(n//12) |
||||
|
n %= 12 |
||||
|
|
||||
|
if n in notes.keys(): |
||||
|
note = notes[n] |
||||
|
mod = '' |
||||
|
|
||||
|
elif notation == 'flats': |
||||
|
note = notes[(n+1)%12] |
||||
|
mod = '♭' |
||||
|
elif notation == 'sharps': |
||||
|
note = notes[(n-1)%12] |
||||
|
mod = '#' |
||||
|
return note+mod+octave |
||||
|
|
||||
|
def complex_note_name(n,note,notation='auto',overkill= False): |
||||
|
if notation not in ('sharps','flats','auto'): |
||||
|
raise ValueError('Notation flag is either "sharps","auto" or "flats."') |
||||
|
if type(note) == str: |
||||
|
note = note.upper() |
||||
|
desired_note = inotes[note] |
||||
|
else: |
||||
|
desired_note = note |
||||
|
note = notes[note] |
||||
|
|
||||
|
octave = n//12 |
||||
|
modify_n = (n-desired_note)%12 |
||||
|
|
||||
|
#complex bit |
||||
|
if notation == 'flats': |
||||
|
modify_n_new = modify_n%(-12) |
||||
|
if modify_n != modify_n_new: |
||||
|
octave += 1 |
||||
|
modify_n = modify_n_new |
||||
|
elif notation == 'sharps': |
||||
|
modify_n_new = modify_n%(12) |
||||
|
if modify_n != modify_n_new: |
||||
|
octave -= 1 |
||||
|
modify_n = modify_n_new |
||||
|
else: |
||||
|
if modify_n > 7: |
||||
|
modify_n %= -12 |
||||
|
#just formating from here on out |
||||
|
if modify_n < 0: |
||||
|
mod = '♭'*abs(modify_n) |
||||
|
elif modify_n > 0: |
||||
|
mod = '#'*modify_n |
||||
|
else: |
||||
|
if overkill: |
||||
|
mod = '♮' |
||||
|
else: |
||||
|
mod = '' |
||||
|
octave = str(octave) |
||||
|
return note+mod+octave |
||||
@ -0,0 +1,24 @@ |
|||||
|
from fingering import fingers |
||||
|
from itertools import * |
||||
|
|
||||
|
def powerset(iterable): |
||||
|
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" |
||||
|
s = list(iterable) |
||||
|
return chain.from_iterable(combinations(s, r) for r in range(1,len(s)+1)) |
||||
|
##for i in range(200): |
||||
|
## print(fingers(i,22)+1) |
||||
|
valves = [2,1,3,5] |
||||
|
dic = {} |
||||
|
altdic = {} |
||||
|
for comb in powerset(valves): |
||||
|
hs = sum(comb) |
||||
|
comb = tuple(map(lambda x: valves.index(x)+1,comb)) |
||||
|
try: |
||||
|
dic[hs] += [comb] |
||||
|
except KeyError: |
||||
|
dic[hs] = [comb] |
||||
|
try: |
||||
|
if len(altdic[hs]) > len(comb): |
||||
|
altdic[hs] = comb |
||||
|
except KeyError: |
||||
|
altdic[hs] = comb |
||||
@ -1,30 +1,68 @@ |
|||||
from load_asset import load |
|
||||
scales = load('scales') |
|
||||
note_names = load('notes') |
|
||||
##def create(scale_type,root): |
|
||||
## |
|
||||
|
import assets |
||||
|
from fingering import fingers |
||||
import convert |
import convert |
||||
class scale: |
class scale: |
||||
|
|
||||
|
|
||||
def __init__(self,*notes): |
def __init__(self,*notes): |
||||
self.notes = scale.number(notes) |
|
||||
|
self.notes = scale.__number__(notes) |
||||
self.raw_intv = self.ri() |
self.raw_intv = self.ri() |
||||
self.root = self.notes[0] |
self.root = self.notes[0] |
||||
|
|
||||
#takes notes from notes to numbers |
#takes notes from notes to numbers |
||||
def number(notes): |
|
||||
print('ran') |
|
||||
return list(map(convert.above_c,notes)) |
|
||||
|
def __number__(notes): |
||||
|
try: |
||||
|
return list(map(int,notes)) |
||||
|
except ValueError: |
||||
|
notes = list(map(convert.num_note,notes)) |
||||
|
for i in range(len(notes)-1): |
||||
|
if notes[i] > notes[i+1]: |
||||
|
notes[i+1] += 12 |
||||
|
return notes |
||||
|
|
||||
#finds raw intervals |
#finds raw intervals |
||||
def ri(self): |
def ri(self): |
||||
notes = self.notes |
notes = self.notes |
||||
return list(map(lambda x: x-notes[0],notes[1:])) |
|
||||
|
try: |
||||
|
return self.raw_intv |
||||
|
except AttributeError: |
||||
|
root = self.notes[0] |
||||
|
return list(map(lambda x: x-root,self.notes)) |
||||
|
|
||||
#returns new scale with given root |
#returns new scale with given root |
||||
def tanspose(self,n): |
|
||||
|
def transpose(self,n): |
||||
if type(n) != int: |
if type(n) != int: |
||||
n = above_c(n) |
|
||||
|
n = convert.num_note(n) |
||||
return scale(*list(map(lambda x: x+n,self.raw_intv))) |
return scale(*list(map(lambda x: x+n,self.raw_intv))) |
||||
|
|
||||
#todo fingers method |
|
||||
|
#prints scale in proper way |
||||
|
def output(self,flag = 'use_simple',notation = 'flats'): |
||||
|
"""Flags are: |
||||
|
'use_simple' |
||||
|
'use_proper'""" |
||||
|
out = [] |
||||
|
note_nums = tuple(assets.inotes.values()) |
||||
|
|
||||
|
if flag == 'use_simple': |
||||
|
return list(map(lambda x: convert.simple_note_name(x,notation = notation),self.notes)) |
||||
|
|
||||
|
elif flag == 'use_proper': |
||||
|
|
||||
|
if self.notes[0]%12 in assets.notes.keys(): |
||||
|
d_n = self.notes[0]%12 |
||||
|
elif notation == 'flats': |
||||
|
d_n = (self.notes[0]+1)%12 |
||||
|
elif notation == 'sharps': |
||||
|
d_n = (self.notes[0]-1)%12 |
||||
|
|
||||
|
offset = note_nums.index(d_n) |
||||
|
|
||||
|
for index in range(len(self.notes)): |
||||
|
count = (offset + index)%len(note_nums) |
||||
|
d_l = note_nums[count] |
||||
|
current_note = self.notes[index] |
||||
|
out.append(convert.complex_note_name(current_note,d_l,notation = 'auto')) |
||||
|
|
||||
|
return out |
||||
|
|
||||
|
def fingers(self,fund): |
||||
|
return list(map(lambda x: fingers(x,fund),self.notes)) |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue