1 #!/usr/bin/env python
2 '''
3 Copyright (C) 2004 Aaron Cyril Spike
5 This file is part of FretFind 2-D.
7 FretFind 2-D is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 FretFind 2-D is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with FretFind 2-D; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 '''
21 import math
23 def ETScale(tones, octave=2.0):
24 octave, tones = float(octave), float(tones)
25 scale = {'steps':[[1.0,1.0]], 'title':'', 'errors':0, 'errorstring':''}
26 if not tones:
27 scale['errors'] += 1
28 scale['errorstring'] = 'Error: Number of tones must be non zero!'
29 else:
30 ratio = octave**(1/tones)
31 scale['title'] = '%s root of %s Equal Temperament' % (tones, octave)
32 scale['steps'].append([ratio,1])
33 return scale
35 def ScalaScale(scala):
36 #initial step 0 or 1/1 is implicit
37 scale = {'steps':[[1.0,1.0]], 'title':'', 'errors':0, 'errorstring':''}
39 #split scale discarding commments
40 lines = [l.strip() for l in scala.strip().splitlines() if not l.strip().startswith('!')]
42 #first line may be blank and contains the title
43 scale['title'] = lines.pop(0)
45 #second line indicates the number of note lines that should follow
46 expected = int(lines.pop(0))
48 #discard blank lines and anything following whitespace
49 lines = [l.split()[0] for l in lines if l != '']
51 if len(lines) != expected:
52 scale['errors'] += 1
53 scale['errorstring'] = 'Error: expected %s more tones but found %s!' % (expected,len(lines))
54 else:
55 for l in lines:
56 #interpret anyline containing a dot as cents
57 if l.find('.') >= 0:
58 num = 2**(float(l)/1200)
59 denom = 1
60 #everything else is a ratio
61 elif l.find('/') >=0:
62 l = l.split('/')
63 num = float(int(l[0]))
64 denom = float(int(l[1]))
65 else:
66 num = float(int(l))
67 denom = 1.0
68 scale['steps'].append([num,denom])
70 if (num < 0) ^ (denom <= 0):
71 scale['errors'] += 1
72 scale['errorstring'] += 'Error at "'+l+'": Negative and undefined ratios are not allowed!\n'
73 return scale