From 5dfbda81bcb263ff97ace49c60d997f8d26eea1c Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Fri, 2 Nov 2018 00:56:54 -0500 Subject: [PATCH] latest google drive version --- Fingering.py | 19 ++++++++++++ assets.py | 26 ++++++++++++++++ convert.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++-- main.py | 24 +++++++++++++++ scale.py | 66 ++++++++++++++++++++++++++++++++--------- 5 files changed, 203 insertions(+), 16 deletions(-) create mode 100644 assets.py diff --git a/Fingering.py b/Fingering.py index e69de29..6445638 100644 --- a/Fingering.py +++ b/Fingering.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 diff --git a/assets.py b/assets.py new file mode 100644 index 0000000..95d67f2 --- /dev/null +++ b/assets.py @@ -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)]} diff --git a/convert.py b/convert.py index 8f9be91..cd8c90c 100644 --- a/convert.py +++ b/convert.py @@ -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[a-gA-G]{1})(?P[♭#]*)(?P\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 diff --git a/main.py b/main.py index e69de29..e7849e6 100644 --- a/main.py +++ b/main.py @@ -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 diff --git a/scale.py b/scale.py index 37f2d9a..60aa7f9 100644 --- a/scale.py +++ b/scale.py @@ -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 class scale: - + def __init__(self,*notes): - self.notes = scale.number(notes) + self.notes = scale.__number__(notes) self.raw_intv = self.ri() self.root = self.notes[0] #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 def ri(self): 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 - def tanspose(self,n): + def transpose(self,n): if type(n) != int: - n = above_c(n) + n = convert.num_note(n) 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))