From bb5eabbd5689cc737597a1e4093ed6e597415eba Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Mon, 29 Sep 2014 21:15:51 -0700 Subject: [PATCH] . --- .dummy | 1 - strings.py | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 1 deletion(-) delete mode 100644 .dummy create mode 100755 strings.py diff --git a/.dummy b/.dummy deleted file mode 100644 index 945c9b4..0000000 --- a/.dummy +++ /dev/null @@ -1 +0,0 @@ -. \ No newline at end of file diff --git a/strings.py b/strings.py new file mode 100755 index 0000000..35d1492 --- /dev/null +++ b/strings.py @@ -0,0 +1,198 @@ +#!/usr/bin/python + +mm_to_in = 0.03937 +scale_length = 648*mm_to_in + +string_sets = { + 'regular light': ( + # (desired note, tension, and type) + ('E4' , 16, 'PL'), + ('B3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('A2' , 16, 'NW'), + ('E2' , 16, 'NW'), + ), + 'light jazz': ( + ('E4' , 24, 'PL'), + ('B3' , 24, 'PL'), + ('G3' , 24, 'NW'), + ('D3' , 24, 'NW'), + ('A2' , 24, 'NW'), + ('E2' , 24, 'NW'), + ), + 'regular light (DADGAD)': ( + ('D4' , 16, 'PL'), + ('A3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('A2' , 16, 'NW'), + ('D2' , 16, 'NW'), + ), + 'open G (6-string)': ( + ('D4' , 16, 'PL'), + ('B3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('B2' , 16, 'NW'), + ('D2' , 16, 'NW'), + ), + 'open G (7-string)': ( + ('D4' , 16, 'PL'), + ('B3' , 16, 'PL'), + ('G3' , 16, 'PL'), + ('D3' , 16, 'NW'), + ('B2' , 16, 'NW'), + ('G2' , 16, 'NW'), + ('D2' , 16, 'NW'), + ), +} + +# D'Addario stock via http://www.daddario.com/upload/tension_chart_13934.pdf +stock = ( +# (product name, unit weight) +# plain steel + ('PL007' , .00001085), + ('PL008' , .00001418), + ('PL0085', .00001601), + ('PL009' , .00001794), + ('PL0095', .00001999), + ('PL010' , .00002215), + ('PL0105', .00002442), + ('PL011' , .00002680), + ('PL0115', .00002930), + ('PL012' , .00003190), + ('PL013' , .00003744), + ('PL0135', .00004037), + ('PL014' , .00004342), + ('PL015' , .00004984), + ('PL016' , .00005671), + ('PL017' , .00006402), + ('PL018' , .00007177), + ('PL019' , .00007997), + ('PL020' , .00008861), + ('PL022' , .00010722), + ('PL024' , .00012760), + ('PL027' , .00014975), + +# nickelplated steel round wound (XL) + ('NW017' , .00005524), + ('NW018' , .00006215), + ('NW019' , .00006947), + ('NW020' , .00007495), + ('NW021' , .00008293), + ('NW022' , .00009184), + ('NW024' , .00010857), + # they have a NW025 used in EXL110BT but it's not listed + ('NW026' , .00012671), + ('NW028' , .00014666), + ('NW030' , .00017236), + ('NW032' , .00019347), + ('NW034' , .00021590), + ('NW036' , .00023964), + ('NW038' , .00026471), + ('NW039' , .00027932), + ('NW042' , .00032279), + ('NW044' , .00035182), + ('NW046' , .00038216), + ('NW048' , .00041382), + ('NW049' , .00043014), + ('NW052' , .00048109), + ('NW054' , .00053838), + ('NW056' , .00057598), + ('NW059' , .00064191), + ('NW060' , .00066542), + ('NW062' , .00070697), + ('NW064' , .00074984), + ('NW066' , .00079889), + ('NW068' , .00084614), + ('NW070' , .00089304), + ('NW072' , .00094124), + ('NW074' , .00098869), + ('NW080' , .00115011), +) + +A = 440 +notes = { + 'C' : 0, + 'D' : 2, + 'E' : 4, + 'F' : 5, + 'G' : 7, + 'A' : 9, + 'B' : 11, +} +rel = (2**(1/12.)) +def note2freq(name): + sharp = name[1] == '#' + flat = name[1] == 'b' + if sharp or flat: + note = name[0:1] + octave = int(name[2]) + else: + note = name[0] + octave = int(name[1]) + num = notes[note] + if sharp: + num += 1 + if flat: + num -= 1 + fullnum = num + 12*(octave - 5) + return A*rel**(fullnum + 3) + +def test(name, expected): + print('{:3} gave {: 9.2f} Hz\nexpected {: 9.2f} Hz'.format(name, note2freq(name), expected)) +if False: + test('C2' , 65.41) + test('Ab4', 415.30) + test('A4' , 440.00) + test('B4' , 493.88) + test('B#4', 523.25) + test('Cb5', 493.88) + test('C5' , 523.25) + print() + test('E4' , 329.63) + test('B3' , 246.94) + test('G3' , 196.00) + test('D3' , 146.83) + test('A2' , 110.00) + test('E2' , 82.41) + +uw_const = 386.4 +def uw2tension(uw, freq): + return (uw*(2*scale_length*freq)**2)/uw_const + +def tension2uw(t, freq): + return (t*uw_const)/(2*scale_length*freq)**2 + +outfmt = '{:<6} at {:> 5.2f} lbs ({:>+4.2f})' +finalfmt = 'total: {:>7.2f} lbs ({:>+5.2f})' +def print_ideal_stock(strings): + total_tension = 0 + total_desired_tension = 0 + for note, tension, kind in strings: + freq = note2freq(note) + uw = tension2uw(tension, freq) + + closest = ('n/a', 0) + for name, stock_uw in stock: + if kind and name[:len(kind)] != kind: + continue + if abs(stock_uw - uw) < abs(closest[1] - uw): + closest = (name, stock_uw) + + closest_tension = uw2tension(closest[1], freq) + diff = closest_tension - tension + print(outfmt.format(closest[0], closest_tension, diff)) + + total_tension += closest_tension + total_desired_tension += tension + + error = total_tension - total_desired_tension + print(finalfmt.format(total_tension, error)) + +print('for a scale length of {:>5.2f} inches'.format(scale_length)) +for name, strings in string_sets.items(): + print() + print('"{}"'.format(name)) + print_ideal_stock(strings)