from rational import Rational
+# Store previously converted pitch for \relative conversion as a global state variable
+previous_pitch = None
+relative_pitches = False
def escape_instrument_string (input_string):
retstring = string.replace (input_string, "\"", "\\\"")
self.newline ()
self._file.close ()
self._file = None
-
-
+
+
class Duration:
def __init__ (self):
self.duration_log = 0
return base * dot_fact * self.factor
-
+
+# Implement the different note names for the various languages
+def pitch_generic (pitch, notenames, accidentals):
+ str = notenames[pitch.step]
+ if pitch.alteration < 0:
+ str += accidentals[0] * (-pitch.alteration)
+ elif pitch.alteration > 0:
+ str += accidentals[3] * (pitch.alteration)
+ return str
+
+def pitch_general (pitch):
+ str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['es', 'eh', 'ih', 'is'])
+ return str.replace ('aes', 'as').replace ('ees', 'es')
+
+def pitch_nederlands (pitch):
+ return pitch_general (pitch)
+
+def pitch_english (pitch):
+ str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['f', 'qf', 'qs', 's'])
+ return str.replace ('aes', 'as').replace ('ees', 'es')
+
+def pitch_deutsch (pitch):
+ str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['es', 'eh', 'ih', 'is'])
+ return str.replace ('hes', 'b').replace ('aes', 'as').replace ('ees', 'es')
+
+def pitch_norsk (pitch):
+ return pitch_deutsch (pitch)
+
+def pitch_svenska (pitch):
+ str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['ess', '', '', 'iss'])
+ return str.replace ('hess', 'b').replace ('aes', 'as').replace ('ees', 'es')
+
+def pitch_italiano (pitch):
+ str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', 'sb', 'sd', 'd'])
+ return str
+
+def pitch_catalan (pitch):
+ return pitch_italiano (pitch)
+
+def pitch_espanol (pitch):
+ str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', '', '', 's'])
+ return str
+
+def pitch_vlaams (pitch):
+ str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', '', '', 'k'])
+ return str
+
+def set_pitch_language (language):
+ global pitch_generating_function
+ function_dict = {
+ "nederlands": pitch_nederlands,
+ "english": pitch_english,
+ "deutsch": pitch_deutsch,
+ "norsk": pitch_norsk,
+ "svenska": pitch_svenska,
+ "italiano": pitch_italiano,
+ "catalan": pitch_catalan,
+ "espanol": pitch_espanol,
+ "vlaams": pitch_vlaams}
+ pitch_generating_function = function_dict.get (language, pitch_general)
+
+# global variable to hold the formatting function.
+pitch_generating_function = pitch_general
+
+
class Pitch:
def __init__ (self):
self.alteration = 0
return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
def ly_step_expression (self):
- str = 'cdefgab'[self.step]
- if self.alteration > 0:
- str += 'is'* (self.alteration)
- elif self.alteration < 0:
- str += 'es'* (-self.alteration)
+ return pitch_generating_function (self)
- return str.replace ('aes', 'as').replace ('ees', 'es')
-
- def ly_expression (self):
- str = self.ly_step_expression ()
+ def absolute_pitch (self):
if self.octave >= 0:
- str += "'" * (self.octave + 1)
+ return "'" * (self.octave + 1)
elif self.octave < -1:
- str += "," * (-self.octave - 1)
-
+ return "," * (-self.octave - 1)
+ else:
+ return ''
+
+ def relative_pitch (self):
+ global previous_pitch
+ if not previous_pitch:
+ previous_pitch = self
+ return self.absolute_pitch ()
+ previous_pitch_steps = previous_pitch.octave * 7 + previous_pitch.step
+ this_pitch_steps = self.octave * 7 + self.step
+ pitch_diff = (this_pitch_steps - previous_pitch_steps)
+ previous_pitch = self
+ if pitch_diff > 3:
+ return "'" * ((pitch_diff + 3) / 7)
+ elif pitch_diff < -3:
+ return "," * ((-pitch_diff + 3) / 7)
+ else:
+ return ""
+
+ def ly_expression (self):
+ str = self.ly_step_expression ()
+ if relative_pitches:
+ str += self.relative_pitch ()
+ else:
+ str += self.absolute_pitch ()
+
return str
def print_ly (self, outputter):
func ('\\%s' % self.mode)
MusicWrapper.print_ly (self, func)
+class RelativeMusic (MusicWrapper):
+ def __init__ (self):
+ MusicWrapper.__init__ (self)
+ self.basepitch = None
+
+ def print_ly (self, func):
+ global previous_pitch
+ global relative_pitches
+ prev_relative_pitches = relative_pitches
+ relative_pitches = True
+ previous_pitch = self.basepitch
+ if not previous_pitch:
+ previous_pitch = Pitch ()
+ func ('\\relative %s%s' % (pitch_generating_function (previous_pitch),
+ previous_pitch.absolute_pitch ()))
+ MusicWrapper.print_ly (self, func)
+ relative_pitches = prev_relative_pitches
+
class TimeScaledMusic (MusicWrapper):
def print_ly (self, func):
func ('\\times %d/%d ' %
elif len (note_events) == 1:
note_events[0].print_ly (printer)
elif note_events:
- pitches = [x.pitch.ly_expression () for x in note_events]
+ global previous_pitch
+ pitches = []
+ basepitch = None
+ for x in note_events:
+ pitches.append (x.pitch.ly_expression ())
+ if not basepitch:
+ basepitch = previous_pitch
printer ('<%s>' % string.join (pitches))
+ previous_pitch = basepitch
note_events[0].duration.print_ly (printer)
else:
pass