OLD | NEW |
1 #!@TARGET_PYTHON@ | 1 #!@TARGET_PYTHON@ |
2 # | 2 # |
3 # midi2ly.py -- LilyPond midi import script | 3 # midi2ly.py -- LilyPond midi import script |
4 | 4 |
5 # This file is part of LilyPond, the GNU music typesetter. | 5 # This file is part of LilyPond, the GNU music typesetter. |
6 # | 6 # |
7 # Copyright (C) 1998--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> | 7 # Copyright (C) 1998--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> |
8 # Jan Nieuwenhuizen <janneke@gnu.org> | 8 # Jan Nieuwenhuizen <janneke@gnu.org> |
9 # | 9 # |
10 # LilyPond is free software: you can redistribute it and/or modify | 10 # LilyPond is free software: you can redistribute it and/or modify |
11 # it under the terms of the GNU General Public License as published by | 11 # it under the terms of the GNU General Public License as published by |
12 # the Free Software Foundation, either version 3 of the License, or | 12 # the Free Software Foundation, either version 3 of the License, or |
13 # (at your option) any later version. | 13 # (at your option) any later version. |
14 # | 14 # |
15 # LilyPond is distributed in the hope that it will be useful, | 15 # LilyPond is distributed in the hope that it will be useful, |
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 # GNU General Public License for more details. | 18 # GNU General Public License for more details. |
19 # | 19 # |
20 # You should have received a copy of the GNU General Public License | 20 # You should have received a copy of the GNU General Public License |
21 # along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | 21 # along with LilyPond. If not, see <http://www.gnu.org/licenses/>. |
22 | 22 |
23 | 23 |
24 ''' | 24 ''' |
25 TODO: | 25 TODO: |
26 ''' | 26 ''' |
27 | 27 |
28 from __future__ import division | 28 |
29 | 29 |
30 import os | 30 import os |
31 import sys | 31 import sys |
32 | 32 |
33 """ | 33 """ |
34 @relocate-preamble@ | 34 @relocate-preamble@ |
35 """ | 35 """ |
36 | 36 |
37 import lilylib as ly | 37 import lilylib as ly |
38 global _;_=ly._ | 38 global _;_=ly._ |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 t = quantise_clocks (t, start_quant_clocks) | 452 t = quantise_clocks (t, start_quant_clocks) |
453 | 453 |
454 if (e[1][0] == midi.NOTE_OFF | 454 if (e[1][0] == midi.NOTE_OFF |
455 or (e[1][0] == midi.NOTE_ON and e[1][2] == 0)): | 455 or (e[1][0] == midi.NOTE_ON and e[1][2] == 0)): |
456 debug ('%d: NOTE OFF: %s' % (t, e[1][1])) | 456 debug ('%d: NOTE OFF: %s' % (t, e[1][1])) |
457 if not e[1][2]: | 457 if not e[1][2]: |
458 debug (' ...treated as OFF') | 458 debug (' ...treated as OFF') |
459 end_note (pitches, notes, t, e[1][1]) | 459 end_note (pitches, notes, t, e[1][1]) |
460 | 460 |
461 elif e[1][0] == midi.NOTE_ON: | 461 elif e[1][0] == midi.NOTE_ON: |
462 if not pitches.has_key (e[1][1]): | 462 if e[1][1] not in pitches: |
463 debug ('%d: NOTE ON: %s' % (t, e[1][1])) | 463 debug ('%d: NOTE ON: %s' % (t, e[1][1])) |
464 pitches[e[1][1]] = (t, e[1][2]) | 464 pitches[e[1][1]] = (t, e[1][2]) |
465 else: | 465 else: |
466 debug ('...ignored') | 466 debug ('...ignored') |
467 | 467 |
468 # all include ALL_NOTES_OFF | 468 # all include ALL_NOTES_OFF |
469 elif (e[1][0] >= midi.ALL_SOUND_OFF | 469 elif (e[1][0] >= midi.ALL_SOUND_OFF |
470 and e[1][0] <= midi.POLY_MODE_ON): | 470 and e[1][0] <= midi.POLY_MODE_ON): |
471 for i in pitches: | 471 for i in pitches: |
472 end_note (pitches, notes, t, i) | 472 end_note (pitches, notes, t, i) |
473 | 473 |
474 elif e[1][0] == midi.META_EVENT: | 474 elif e[1][0] == midi.META_EVENT: |
475 if e[1][1] == midi.END_OF_TRACK: | 475 if e[1][1] == midi.END_OF_TRACK: |
476 for i in pitches: | 476 for i in pitches: |
477 end_note (pitches, notes, t, i) | 477 end_note (pitches, notes, t, i) |
478 break | 478 break |
479 | 479 |
480 elif e[1][1] == midi.SET_TEMPO: | 480 elif e[1][1] == midi.SET_TEMPO: |
481 (u0, u1, u2) = map (ord, e[1][2]) | 481 (u0, u1, u2) = list(map (ord, e[1][2])) |
482 us_per_4 = u2 + 256 * (u1 + 256 * u0) | 482 us_per_4 = u2 + 256 * (u1 + 256 * u0) |
483 seconds_per_1 = us_per_4 * 4 / 1e6 | 483 seconds_per_1 = us_per_4 * 4 / 1e6 |
484 music.append ((t, Tempo (seconds_per_1))) | 484 music.append ((t, Tempo (seconds_per_1))) |
485 elif e[1][1] == midi.TIME_SIGNATURE: | 485 elif e[1][1] == midi.TIME_SIGNATURE: |
486 (num, dur, clocks4, count32) = map (ord, e[1][2]) | 486 (num, dur, clocks4, count32) = list(map (ord, e[1][2])) |
487 den = 2 ** dur | 487 den = 2 ** dur |
488 music.append ((t, Time (num, den))) | 488 music.append ((t, Time (num, den))) |
489 elif e[1][1] == midi.KEY_SIGNATURE: | 489 elif e[1][1] == midi.KEY_SIGNATURE: |
490 (alterations, minor) = map (ord, e[1][2]) | 490 (alterations, minor) = list(map (ord, e[1][2])) |
491 sharps = 0 | 491 sharps = 0 |
492 flats = 0 | 492 flats = 0 |
493 if alterations < 127: | 493 if alterations < 127: |
494 sharps = alterations | 494 sharps = alterations |
495 else: | 495 else: |
496 flats = 256 - alterations | 496 flats = 256 - alterations |
497 | 497 |
498 k = Key (sharps, flats, minor) | 498 k = Key (sharps, flats, minor) |
499 if not t and global_options.key: | 499 if not t and global_options.key: |
500 # At t == 0, a set --key overrides us | 500 # At t == 0, a set --key overrides us |
(...skipping 17 matching lines...) Expand all Loading... |
518 | 518 |
519 elif (e[1][1] >= midi.SEQUENCE_NUMBER | 519 elif (e[1][1] >= midi.SEQUENCE_NUMBER |
520 and e[1][1] <= midi.CUE_POINT): | 520 and e[1][1] <= midi.CUE_POINT): |
521 text = Text (e[1][1], e[1][2]) | 521 text = Text (e[1][1], e[1][2]) |
522 text.track = self | 522 text.track = self |
523 music.append ((t, text)) | 523 music.append ((t, text)) |
524 if (text.type == midi.SEQUENCE_TRACK_NAME): | 524 if (text.type == midi.SEQUENCE_TRACK_NAME): |
525 self.name = text.text | 525 self.name = text.text |
526 else: | 526 else: |
527 if global_options.verbose: | 527 if global_options.verbose: |
528 sys.stderr.write ("SKIP: %s\n" % `e`) | 528 sys.stderr.write ("SKIP: %s\n" % repr(e)) |
529 else: | 529 else: |
530 if global_options.verbose: | 530 if global_options.verbose: |
531 sys.stderr.write ("SKIP: %s\n" % `e`) | 531 sys.stderr.write ("SKIP: %s\n" % repr(e)) |
532 | 532 |
533 if last_lyric: | 533 if last_lyric: |
534 # last_lyric.clocks = t - last_time | 534 # last_lyric.clocks = t - last_time |
535 # hmm | 535 # hmm |
536 last_lyric.clocks = clocks_per_4 | 536 last_lyric.clocks = clocks_per_4 |
537 music.append ((last_time, last_lyric)) | 537 music.append ((last_time, last_lyric)) |
538 last_lyric = 0 | 538 last_lyric = 0 |
539 | 539 |
540 i = 0 | 540 i = 0 |
541 while len (notes): | 541 while len (notes): |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 | 786 |
787 def lst_append (lst, x): | 787 def lst_append (lst, x): |
788 lst.append (x) | 788 lst.append (x) |
789 return lst | 789 return lst |
790 | 790 |
791 def get_voice_layout (average_pitch): | 791 def get_voice_layout (average_pitch): |
792 d = {} | 792 d = {} |
793 for i in range (len (average_pitch)): | 793 for i in range (len (average_pitch)): |
794 d[average_pitch[i]] = lst_append (d.get (average_pitch[i], []), i) | 794 d[average_pitch[i]] = lst_append (d.get (average_pitch[i], []), i) |
795 s = list (reversed (sorted (average_pitch))) | 795 s = list (reversed (sorted (average_pitch))) |
796 non_empty = len (filter (lambda x: x, s)) | 796 non_empty = len ([x for x in s if x]) |
797 names = ['One', 'Two'] | 797 names = ['One', 'Two'] |
798 if non_empty > 2: | 798 if non_empty > 2: |
799 names = ['One', 'Three', 'Four', 'Two'] | 799 names = ['One', 'Three', 'Four', 'Two'] |
800 layout = map (lambda x: '', range (len (average_pitch))) | 800 layout = ['' for x in range (len (average_pitch))] |
801 for i, n in zip (s, names): | 801 for i, n in zip (s, names): |
802 if i: | 802 if i: |
803 v = d[i] | 803 v = d[i] |
804 if type (v) == list: | 804 if type (v) == list: |
805 d[i] = v[1:] | 805 d[i] = v[1:] |
806 v = v[0] | 806 v = v[0] |
807 layout[v] = n | 807 layout[v] = n |
808 return layout | 808 return layout |
809 | 809 |
810 def dump_track (track, n): | 810 def dump_track (track, n): |
811 s = '\n' | 811 s = '\n' |
812 track_name = get_track_name (n) | 812 track_name = get_track_name (n) |
813 | 813 |
814 average_pitch = track_average_pitch (track) | 814 average_pitch = track_average_pitch (track) |
815 voices = len (filter (lambda x: x, average_pitch[1:])) | 815 voices = len ([x for x in average_pitch[1:] if x]) |
816 clef = get_best_clef (average_pitch[0]) | 816 clef = get_best_clef (average_pitch[0]) |
817 | 817 |
818 c = 0 | 818 c = 0 |
819 vv = 0 | 819 vv = 0 |
820 for channel in track: | 820 for channel in track: |
821 v = 0 | 821 v = 0 |
822 channel_name = get_channel_name (c) | 822 channel_name = get_channel_name (c) |
823 c += 1 | 823 c += 1 |
824 for voice in channel: | 824 for voice in channel: |
825 voice_name = get_voice_name (v) | 825 voice_name = get_voice_name (v) |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 start_quant_clocks = clocks_per_1 / global_options.start_quant | 960 start_quant_clocks = clocks_per_1 / global_options.start_quant |
961 | 961 |
962 if global_options.duration_quant: | 962 if global_options.duration_quant: |
963 duration_quant_clocks = clocks_per_1 / global_options.duration_quant | 963 duration_quant_clocks = clocks_per_1 / global_options.duration_quant |
964 | 964 |
965 allowed_tuplet_clocks = [] | 965 allowed_tuplet_clocks = [] |
966 for (dur, num, den) in global_options.allowed_tuplets: | 966 for (dur, num, den) in global_options.allowed_tuplets: |
967 allowed_tuplet_clocks.append (clocks_per_1 / dur * num / den) | 967 allowed_tuplet_clocks.append (clocks_per_1 / dur * num / den) |
968 | 968 |
969 if global_options.verbose: | 969 if global_options.verbose: |
970 print 'allowed tuplet clocks:', allowed_tuplet_clocks | 970 print('allowed tuplet clocks:', allowed_tuplet_clocks) |
971 | 971 |
972 tracks = [create_track (t) for t in midi_dump[1]] | 972 tracks = [create_track (t) for t in midi_dump[1]] |
973 # urg, parse all global track events, such as Key first | 973 # urg, parse all global track events, such as Key first |
974 # this fixes key in different voice/staff problem | 974 # this fixes key in different voice/staff problem |
975 for t in tracks: | 975 for t in tracks: |
976 t.music = t.parse () | 976 t.music = t.parse () |
977 prev = None | 977 prev = None |
978 staves = [] | 978 staves = [] |
979 for t in tracks: | 979 for t in tracks: |
980 voices = t.get_voices () | 980 voices = t.get_voices () |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 action='store_true') | 1110 action='store_true') |
1111 p.version = 'midi2ly (LilyPond) @TOPLEVEL_VERSION@' | 1111 p.version = 'midi2ly (LilyPond) @TOPLEVEL_VERSION@' |
1112 p.add_option ('--version', | 1112 p.add_option ('--version', |
1113 action='version', | 1113 action='version', |
1114 help=_ ('show version number and exit')) | 1114 help=_ ('show version number and exit')) |
1115 p.add_option ('-w', '--warranty', help=_ ('show warranty and copyright'), | 1115 p.add_option ('-w', '--warranty', help=_ ('show warranty and copyright'), |
1116 action='store_true',) | 1116 action='store_true',) |
1117 p.add_option ('-x', '--text-lyrics', help=_ ('treat every text as a lyric'), | 1117 p.add_option ('-x', '--text-lyrics', help=_ ('treat every text as a lyric'), |
1118 action='store_true') | 1118 action='store_true') |
1119 | 1119 |
1120 p.add_option_group (ly.display_encode (_ ('Examples')), | 1120 p.add_option_group (_ ('Examples'), |
1121 description = r''' | 1121 description = r''' |
1122 $ midi2ly --key=-2:1 --duration-quant=32 --allow-tuplet=4*2/3 --allow-tuplet=2
*4/3 foo.midi | 1122 $ midi2ly --key=-2:1 --duration-quant=32 --allow-tuplet=4*2/3 --allow-tuplet=2
*4/3 foo.midi |
1123 ''') | 1123 ''') |
1124 p.add_option_group ('', | 1124 p.add_option_group ('', |
1125 description=( | 1125 description=( |
1126 _ ('Report bugs via %s') | 1126 _ ('Report bugs via %s') |
1127 % 'bug-lilypond@gnu.org') + '\n') | 1127 % 'bug-lilypond@gnu.org') + '\n') |
1128 return p | 1128 return p |
1129 | 1129 |
1130 | 1130 |
1131 | 1131 |
1132 def do_options (): | 1132 def do_options (): |
1133 opt_parser = get_option_parser () | 1133 opt_parser = get_option_parser () |
1134 (options, args) = opt_parser.parse_args () | 1134 (options, args) = opt_parser.parse_args () |
1135 | 1135 |
1136 if options.warranty: | 1136 if options.warranty: |
1137 warranty () | 1137 warranty () |
1138 sys.exit (0) | 1138 sys.exit (0) |
1139 | 1139 |
1140 if not args or args[0] == '-': | 1140 if not args or args[0] == '-': |
1141 opt_parser.print_help () | 1141 opt_parser.print_help () |
1142 ly.stderr_write ('\n%s: %s %s\n' % (program_name, _ ('error: '), | 1142 ly.stderr_write ('\n%s: %s %s\n' % (program_name, _ ('error: '), |
1143 _ ('no files specified on command line.'))) | 1143 _ ('no files specified on command line.'))) |
1144 sys.exit (2) | 1144 sys.exit (2) |
1145 | 1145 |
1146 if options.duration_quant: | 1146 if options.duration_quant: |
1147 options.duration_quant = int (options.duration_quant) | 1147 options.duration_quant = int (options.duration_quant) |
1148 | 1148 |
1149 if options.key: | 1149 if options.key: |
1150 (alterations, minor) = map (int, (options.key + ':0').split (':'))[0:2] | 1150 (alterations, minor) = list(map (int, (options.key + ':0').split (':')))
[0:2] |
1151 sharps = 0 | 1151 sharps = 0 |
1152 flats = 0 | 1152 flats = 0 |
1153 if alterations >= 0: | 1153 if alterations >= 0: |
1154 sharps = alterations | 1154 sharps = alterations |
1155 else: | 1155 else: |
1156 flats = - alterations | 1156 flats = - alterations |
1157 options.key = Key (sharps, flats, minor) | 1157 options.key = Key (sharps, flats, minor) |
1158 | 1158 |
1159 if options.start_quant: | 1159 if options.start_quant: |
1160 options.start_quant = int (options.start_quant) | 1160 options.start_quant = int (options.start_quant) |
1161 | 1161 |
1162 global bar_max | 1162 global bar_max |
1163 if options.preview: | 1163 if options.preview: |
1164 bar_max = 4 | 1164 bar_max = 4 |
1165 | 1165 |
1166 options.allowed_tuplets = [map (int, a.replace ('/','*').split ('*')) | 1166 options.allowed_tuplets = [list(map (int, a.replace ('/','*').split ('*'))) |
1167 for a in options.allowed_tuplets] | 1167 for a in options.allowed_tuplets] |
1168 | 1168 |
1169 if options.verbose: | 1169 if options.verbose: |
1170 sys.stderr.write ('Allowed tuplets: %s\n' % `options.allowed_tuplets`) | 1170 sys.stderr.write ('Allowed tuplets: %s\n' % repr(options.allowed_tuplets
)) |
1171 | 1171 |
1172 global global_options | 1172 global global_options |
1173 global_options = options | 1173 global_options = options |
1174 | 1174 |
1175 return args | 1175 return args |
1176 | 1176 |
1177 def main (): | 1177 def main (): |
1178 files = do_options () | 1178 files = do_options () |
1179 | 1179 |
1180 exts = ['.midi', '.mid', '.MID'] | 1180 exts = ['.midi', '.mid', '.MID'] |
(...skipping 15 matching lines...) Expand all Loading... |
1196 elif (global_options.output[-1] == os.sep | 1196 elif (global_options.output[-1] == os.sep |
1197 or os.path.isdir (global_options.output)): | 1197 or os.path.isdir (global_options.output)): |
1198 outdir = global_options.output | 1198 outdir = global_options.output |
1199 outbase = os.path.basename (g) | 1199 outbase = os.path.basename (g) |
1200 o = os.path.join (outdir, outbase + '-midi.ly') | 1200 o = os.path.join (outdir, outbase + '-midi.ly') |
1201 else: | 1201 else: |
1202 o = global_options.output | 1202 o = global_options.output |
1203 (outdir, outbase) = os.path.split (o) | 1203 (outdir, outbase) = os.path.split (o) |
1204 | 1204 |
1205 if outdir and outdir != '.' and not os.path.exists (outdir): | 1205 if outdir and outdir != '.' and not os.path.exists (outdir): |
1206 os.mkdir (outdir, 0777) | 1206 os.mkdir (outdir, 0o777) |
1207 | 1207 |
1208 convert_midi (f, o) | 1208 convert_midi (f, o) |
1209 | 1209 |
1210 if __name__ == '__main__': | 1210 if __name__ == '__main__': |
1211 main () | 1211 main () |
OLD | NEW |