-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlily2stream.py
99 lines (87 loc) · 2.82 KB
/
lily2stream.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import ly.musicxml
import music21
class Lily2Stream(object):
"""
class that converts simple lilypond fragments (containing only notes,rests and chords)
to music21 streams
"""
def __init__(self):
pass
@staticmethod
def parse(lytext=""):
"""
convert from lilypond to stream
:param lytext: string containing simple lilypond fragment, e.g. "{ a b c }"
:return: music21 stream
"""
e = ly.musicxml.writer()
e.parse_text(lytext)
xml = e.musicxml()
m = xml.tostring().decode("utf-8")
s = music21.converter.parse(m, format="musicxml")
return s
@staticmethod
def unparse(stream):
"""
convert from music21 stream to lilypond fragment
:param stream
:return: string containing lilypond code fragment
"""
lpc = music21.lily.translate.LilypondConverter()
lp_music_list = music21.lily.lilyObjects.LyMusicList()
lpc.context = lp_music_list
lpc.appendObjectsToContextFromStream(stream)
return str(lpc.context)
if __name__ == "__main__":
# first triplet of single notes -> these work well
l = Lily2Stream()
s = l.parse("{ \\times2/3 { a8 b c } }")
s.show("txt")
# looks ok:
#{0.0} <music21.metadata.Metadata object at 0x7feb9e3e42e8>
#{0.0} <music21.stream.Part 0x7feb9e3e4668>
# {0.0} <music21.instrument.Instrument P1: >
# {0.0} <music21.stream.Measure 1 offset=0.0>
# {0.0} <music21.clef.TrebleClef>
# {0.0} <music21.meter.TimeSignature 4/4>
# {0.0} <music21.note.Note A>
# {0.3333} <music21.note.Note B>
# {0.6667} <music21.note.Note C>
#s.show("musicxml") # looks ok
print(l.unparse(s))
# looks ok:
# \new Staff = xawweyfawxbxyzy { \partial 32*8
# \clef "treble"
# \time 4/4
# \times 2/3 { a 8
# b 8
# c 8
# }
#
# \bar "|" %{ end measure 1 %}
# }
# now triplet of chords -> these do not serialize to lilypond correctly
# (but they do serialize to musicxml correctly)
s = l.parse("{ \\times2/3 { <a c>8 <a b> <a c> } }")
s.show("txt")
#looks ok:
#{0.0} <music21.metadata.Metadata object at 0x7feb9be4e390>
#{0.0} <music21.stream.Part 0x7feb9be4ea90>
# {0.0} <music21.instrument.Instrument P1: >
# {0.0} <music21.stream.Measure 1 offset=0.0>
# {0.0} <music21.clef.TrebleClef>
# {0.0} <music21.meter.TimeSignature 4/4>
# {0.0} <music21.chord.Chord A3 C3>
# {0.3333} <music21.chord.Chord A3 B3>
# {0.6667} <music21.chord.Chord A3 C3>
#s.show("musicxml") # looks ok
print(l.unparse(s))
#wrong: triplet lost
#\new Staff = xawweyfzfedaaaw { \partial 32*8
# \clef "treble"
# \time 4/4
# < a c > 8
# < a b > 8
# < a c > 8
# \bar "|" %{ end measure 1 %}
# }