+ for i in global_options.include_header:
+ s += '\n%% included from %(i)s\n' % locals ()
+ s += open (i).read ()
+ if s[-1] != '\n':
+ s += '\n'
+ s += '% end\n'
+
+ for i, t in enumerate (staves):
+ s += t.dump (i)
+
+ s += '\n\\score {\n <<\n'
+
+ control_track = False
+ i = 0
+ for i, staff in enumerate (staves):
+ track_name = get_track_name (i)
+ item = track_first_item (staff.voices)
+ staff_name = track_name
+ context = None
+ if not i and not item and len (staves) > 1:
+ control_track = track_name
+ continue
+ elif (item and item.__class__ == Note):
+ context = 'Staff'
+ if control_track:
+ s += ' \\context %(context)s=%(staff_name)s \\%(control_track)s\n' % locals ()
+ elif item and item.__class__ == Text:
+ context = 'Lyrics'
+ if context:
+ s += ' \\context %(context)s=%(staff_name)s \\%(track_name)s\n' % locals ()
+
+ s = s + ''' >>
+ \layout {}
+ \midi {}
+}
+'''
+
+ if not global_options.quiet:
+ progress (_ ("%s output to `%s'...") % ('LY', out_file))
+
+ if out_file == '-':
+ handle = sys.stdout
+ else:
+ handle = open (out_file, 'w')
+
+ handle.write (s)
+ handle.close ()
+
+
+def get_option_parser ():
+ p = ly.get_option_parser (usage=_ ("%s [OPTION]... FILE") % 'midi2ly',
+ description=_ ("Convert %s to LilyPond input.\n") % 'MIDI',
+ add_help_option=False)
+
+ p.add_option ('-a', '--absolute-pitches',
+ action='store_true',
+ help=_ ('print absolute pitches'))
+ p.add_option ('-d', '--duration-quant',
+ metavar=_ ('DUR'),
+ help=_ ('quantise note durations on DUR'))
+ p.add_option ('-D', '--debug',
+ action='store_true',
+ help=_ ('debug printing'))
+ p.add_option ('-e', '--explicit-durations',
+ action='store_true',
+ help=_ ('print explicit durations'))
+ p.add_option('-h', '--help',
+ action='help',
+ help=_ ('show this help and exit'))
+ p.add_option('-i', '--include-header',
+ help=_ ('prepend FILE to output'),
+ action='append',
+ default=[],
+ metavar=_ ('FILE'))
+ p.add_option('-k', '--key', help=_ ('set key: ALT=+sharps|-flats; MINOR=1'),
+ metavar=_ ('ALT[:MINOR]'),
+ default=None),
+ p.add_option ('-o', '--output', help=_ ('write output to FILE'),
+ metavar=_ ('FILE'),
+ action='store')
+ p.add_option ('-p', '--preview', help=_ ('preview of first 4 bars'),
+ action='store_true')
+ p.add_option ('-q', '--quiet',
+ action="store_true",
+ help=_ ("suppress progress messages and warnings about excess voices"))
+ p.add_option ('-s', '--start-quant',help= _ ('quantise note starts on DUR'),
+ metavar=_ ('DUR'))
+ p.add_option ('-S', '--skip',
+ action = "store_true",
+ help =_ ("use s instead of r for rests"))
+ p.add_option ('-t', '--allow-tuplet',
+ metavar=_ ('DUR*NUM/DEN'),
+ action = 'append',
+ dest='allowed_tuplets',
+ help=_ ('allow tuplet durations DUR*NUM/DEN'),
+ default=[])
+ p.add_option ('-V', '--verbose', help=_ ('be verbose'),
+ action='store_true')
+ p.version = 'midi2ly (LilyPond) @TOPLEVEL_VERSION@'
+ p.add_option ('--version',
+ action='version',
+ help=_ ('show version number and exit'))
+ p.add_option ('-w', '--warranty', help=_ ('show warranty and copyright'),
+ action='store_true',)
+ p.add_option ('-x', '--text-lyrics', help=_ ('treat every text as a lyric'),
+ action='store_true')
+
+ p.add_option_group (ly.display_encode (_ ('Examples')),
+ description = r'''
+ $ midi2ly --key=-2:1 --duration-quant=32 --allow-tuplet=4*2/3 --allow-tuplet=2*4/3 foo.midi
+''')
+ p.add_option_group ('',
+ description=(
+ _ ('Report bugs via %s')
+ % 'http://post.gmane.org/post.php'
+ '?group=gmane.comp.gnu.lilypond.bugs') + '\n')
+ return p
+
+
+
+def do_options ():
+ opt_parser = get_option_parser ()
+ (options, args) = opt_parser.parse_args ()
+
+ if options.warranty:
+ warranty ()
+ sys.exit (0)
+
+ if not args or args[0] == '-':
+ opt_parser.print_help ()
+ ly.stderr_write ('\n%s: %s %s\n' % (program_name, _ ('error: '),
+ _ ('no files specified on command line.')))
+ sys.exit (2)
+
+ if options.duration_quant:
+ options.duration_quant = int (options.duration_quant)
+
+ if options.key:
+ (alterations, minor) = map (int, (options.key + ':0').split (':'))[0:2]
+ sharps = 0
+ flats = 0
+ if alterations >= 0:
+ sharps = alterations
+ else:
+ flats = - alterations
+ options.key = Key (sharps, flats, minor)
+
+ if options.start_quant:
+ options.start_quant = int (options.start_quant)
+
+ global bar_max
+ if options.preview:
+ bar_max = 4
+
+ options.allowed_tuplets = [map (int, a.replace ('/','*').split ('*'))
+ for a in options.allowed_tuplets]
+
+ if options.verbose:
+ sys.stderr.write ('Allowed tuplets: %s\n' % `options.allowed_tuplets`)
+
+ global global_options
+ global_options = options
+
+ return args
+
+def main ():
+ files = do_options ()
+
+ exts = ['.midi', '.mid', '.MID']
+ for f in files:
+ g = f
+ for e in exts:
+ g = strip_extension (g, e)
+ if not os.path.exists (f):
+ for e in exts:
+ n = g + e
+ if os.path.exists (n):
+ f = n
+ break
+
+ if not global_options.output:
+ outdir = '.'
+ outbase = os.path.basename (g)
+ o = outbase + '-midi.ly'
+ elif (global_options.output[-1] == os.sep
+ or os.path.isdir (global_options.output)):
+ outdir = global_options.output
+ outbase = os.path.basename (g)
+ o = os.path.join (outdir, outbase + '-midi.ly')
+ else:
+ o = global_options.output
+ (outdir, outbase) = os.path.split (o)
+
+ if outdir and outdir != '.' and not os.path.exists (outdir):
+ os.mkdir (outdir, 0777)
+
+ convert_midi (f, o)
+
+if __name__ == '__main__':
+ main ()