3 # once upon a rainy monday afternoon.
10 program_name = 'abc-to-ly'
21 global_voice_stuff = []
23 global_key = [0] * 7 # UGH
32 def __init__ (self, n, d = 1):
37 g = gcd (self.num, self.den)
38 self.num = self.num / g
39 self.den = self.den /g
44 def __sub__ (self, other):
49 def dump_header (hdr):
52 print '%s = "%s";\n'% (k,hdr[k])
55 def set_default_length (s):
56 m = re.search ('1/([0-9]+)', s)
58 __main__.default_len = string.atoi ( m.group (1))
67 print 'can\'t open file: ' + f + '\n'
71 print 'gulped empty file: ' + f + '\n'
76 # pitch manipulation. Tuples are (name, alteration).
77 # 0 is (central) C. Alteration -1 is a flat, Alteration +1 is a sharp
79 def semitone_pitch (tup):
92 def fifth_above_pitch (tup):
93 (n, a) = (tup[0] + 4, tup[1])
95 difference = 7 - (semitone_pitch ((n,a)) - semitone_pitch (tup))
106 (t,a) = fifth_above_pitch (p)
107 if semitone_pitch((t,a)) % 12 == 0:
119 (t,a) = quart_above_pitch (p)
120 if semitone_pitch((t,a)) % 12 == 0:
126 def quart_above_pitch (tup):
127 (n, a) = (tup[0] + 3, tup[1])
129 difference = 5 - (semitone_pitch ((n,a)) - semitone_pitch (tup))
137 intkey = (ord (k[0]) - ord('a') + 5) % 7
141 if k and k[0] == 'b':
144 elif k and k[0] == '#':
148 keytup = (intkey, intkeyacc)
150 sharp_key_seq = sharp_keys ()
151 flat_key_seq = flat_keys ()
155 if keytup in sharp_key_seq:
157 key_count = sharp_key_seq.index (keytup)
158 accseq = map (lambda x: (4*x -1 ) % 7, range (1, key_count + 1))
160 elif keytup in flat_key_seq:
162 key_count = flat_key_seq.index (keytup)
163 accseq = map (lambda x: (3*x + 3 ) % 7, range (1, key_count + 1))
169 key_table[a] = key_table[a] + accsign
174 def try_parse_header_line (ln):
175 m = re.match ('^(.): *(.*)$', ln)
183 global_voice_stuff.append ('\\time %s;' % a)
185 __main__.global_key =compute_key (a)# ugh.
187 global_voice_stuff.append ('\\key %s;' % a)
189 header ['origin'] = a
191 header ['crossRefNumber'] = a
196 header ['history'] = a
200 header ['subtitle'] = a
202 set_default_length (ln)
207 def pitch_to_mudela_name (name, acc):
217 return chr (name + ord('c')) + s * acc
219 def octave_to_mudela_quotes (o):
231 while str[0] in DIGITS:
232 durstr = durstr + str[0]
237 n =string.atoi (durstr)
241 def duration_to_mudela_duration (multiply_tup, defaultlen, dots):
244 # (num / den) / defaultlen < 1/base
245 while base * multiply_tup[0] < defaultlen * multiply_tup[1]:
249 return '%d%s' % ( base, '.'* dots)
257 # WAT IS ABC EEN ONTZETTENDE PROGRAMMEERPOEP !
258 def try_parse_note (str, parser_state):
278 if str[0] in "ABCDEFG":
279 str = string.lower (str[0]) + str[1:]
284 if str[0] in "abcdefg":
285 notename = (ord(str[0]) - ord('a') + 5)%7
288 return str # failed; not a note!
293 while str[0] == '\'':
298 den = parser_state.next_den
299 parser_state.next_den = 1
301 (str, num) = parse_num (str)
310 (str, d) =parse_num (str)
314 current_dots = parser_state.next_dots
315 parser_state.next_dots = 0
318 current_dots = current_dots + 1;
319 parser_state.next_den = parser_state.next_den * 2
324 parser_state.next_dots = parser_state.next_dots + 1
328 print '%s%s%s' % (pitch_to_mudela_name(notename, acc + global_key[notename]) , octave_to_mudela_quotes (octave),
329 duration_to_mudela_duration ((num,den), default_len, current_dots))
339 def junk_space (str):
340 while str and str[0] in '\t\n ':
345 def try_parse_escape (str):
356 def try_parse_bar (str):
363 def try_parse_body_line (ln, state):
365 while ln and ln != prev_ln:
367 ln = try_parse_note (ln, state)
368 ln = try_parse_bar (ln)
370 ln = try_parse_escape (ln)
384 state = Parser_state ()
386 if re.match ('^[\t ]*(%.*)?$', l):
390 m = try_parse_header_line (l)
395 m = try_parse_body_line (l,state)
399 print '%s %s' % (program_name, version)
403 This is a disfunctional ABC to mudela convertor. It only gulps input, and
404 says huh when confused. Does not do chords. Go ahead and fix me.
406 -h, --help this help.
412 (options, files) = getopt.getopt (sys.argv[1:], 'h', ['help'])
417 if o== '--help' or o == '-h':
430 print global_voice_stuff, 1