musicality 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +8 -1
  3. data/bin/midify +3 -4
  4. data/examples/composition/auto_counterpoint.rb +53 -0
  5. data/examples/composition/part_generator.rb +51 -0
  6. data/examples/composition/scale_exercise.rb +41 -0
  7. data/examples/{hip.rb → notation/hip.rb} +1 -1
  8. data/examples/{missed_connection.rb → notation/missed_connection.rb} +1 -1
  9. data/examples/{song1.rb → notation/song1.rb} +1 -1
  10. data/examples/{song2.rb → notation/song2.rb} +1 -1
  11. data/lib/musicality.rb +34 -4
  12. data/lib/musicality/composition/generation/counterpoint_generator.rb +153 -0
  13. data/lib/musicality/composition/generation/random_rhythm_generator.rb +39 -0
  14. data/lib/musicality/composition/model/pitch_class.rb +33 -0
  15. data/lib/musicality/composition/model/pitch_classes.rb +22 -0
  16. data/lib/musicality/composition/model/scale.rb +34 -0
  17. data/lib/musicality/composition/model/scale_class.rb +37 -0
  18. data/lib/musicality/composition/model/scale_classes.rb +91 -0
  19. data/lib/musicality/composition/note_generation.rb +31 -0
  20. data/lib/musicality/composition/transposition.rb +8 -0
  21. data/lib/musicality/composition/util/adding_sequence.rb +24 -0
  22. data/lib/musicality/composition/util/biinfinite_sequence.rb +130 -0
  23. data/lib/musicality/composition/util/compound_sequence.rb +44 -0
  24. data/lib/musicality/composition/util/probabilities.rb +20 -0
  25. data/lib/musicality/composition/util/random_sampler.rb +26 -0
  26. data/lib/musicality/composition/util/repeating_sequence.rb +24 -0
  27. data/lib/musicality/errors.rb +2 -0
  28. data/lib/musicality/notation/conversion/score_conversion.rb +1 -1
  29. data/lib/musicality/notation/conversion/score_converter.rb +3 -3
  30. data/lib/musicality/notation/model/link.rb +26 -24
  31. data/lib/musicality/notation/model/links.rb +11 -0
  32. data/lib/musicality/notation/model/note.rb +14 -15
  33. data/lib/musicality/notation/model/part.rb +3 -3
  34. data/lib/musicality/notation/model/pitch.rb +8 -0
  35. data/lib/musicality/notation/model/score.rb +70 -44
  36. data/lib/musicality/notation/model/symbols.rb +22 -0
  37. data/lib/musicality/notation/packing/score_packing.rb +2 -3
  38. data/lib/musicality/notation/parsing/articulation_parsing.rb +4 -4
  39. data/lib/musicality/notation/parsing/articulation_parsing.treetop +2 -2
  40. data/lib/musicality/notation/parsing/link_nodes.rb +2 -14
  41. data/lib/musicality/notation/parsing/link_parsing.rb +9 -107
  42. data/lib/musicality/notation/parsing/link_parsing.treetop +4 -12
  43. data/lib/musicality/notation/parsing/note_node.rb +23 -21
  44. data/lib/musicality/notation/parsing/note_parsing.rb +70 -70
  45. data/lib/musicality/notation/parsing/note_parsing.treetop +6 -3
  46. data/lib/musicality/notation/parsing/pitch_node.rb +4 -2
  47. data/lib/musicality/performance/conversion/score_collator.rb +3 -3
  48. data/lib/musicality/performance/midi/midi_util.rb +13 -6
  49. data/lib/musicality/performance/midi/score_sequencing.rb +17 -0
  50. data/lib/musicality/printing/lilypond/errors.rb +5 -0
  51. data/lib/musicality/printing/lilypond/meter_engraving.rb +11 -0
  52. data/lib/musicality/printing/lilypond/note_engraving.rb +53 -0
  53. data/lib/musicality/printing/lilypond/part_engraver.rb +12 -0
  54. data/lib/musicality/printing/lilypond/pitch_engraving.rb +30 -0
  55. data/lib/musicality/printing/lilypond/score_engraver.rb +78 -0
  56. data/lib/musicality/version.rb +1 -1
  57. data/spec/composition/generation/random_rhythm_generator_spec.rb +50 -0
  58. data/spec/composition/model/pitch_class_spec.rb +75 -0
  59. data/spec/composition/model/pitch_classes_spec.rb +24 -0
  60. data/spec/composition/model/scale_class_spec.rb +98 -0
  61. data/spec/composition/model/scale_spec.rb +110 -0
  62. data/spec/composition/note_generation_spec.rb +113 -0
  63. data/spec/composition/transposition_spec.rb +17 -0
  64. data/spec/composition/util/adding_sequence_spec.rb +176 -0
  65. data/spec/composition/util/compound_sequence_spec.rb +50 -0
  66. data/spec/composition/util/probabilities_spec.rb +39 -0
  67. data/spec/composition/util/random_sampler_spec.rb +47 -0
  68. data/spec/composition/util/repeating_sequence_spec.rb +151 -0
  69. data/spec/notation/conversion/score_conversion_spec.rb +3 -3
  70. data/spec/notation/conversion/score_converter_spec.rb +24 -24
  71. data/spec/notation/model/link_spec.rb +27 -25
  72. data/spec/notation/model/note_spec.rb +9 -6
  73. data/spec/notation/model/pitch_spec.rb +24 -1
  74. data/spec/notation/model/score_spec.rb +57 -16
  75. data/spec/notation/packing/score_packing_spec.rb +134 -206
  76. data/spec/notation/parsing/articulation_parsing_spec.rb +1 -8
  77. data/spec/notation/parsing/convenience_methods_spec.rb +1 -1
  78. data/spec/notation/parsing/link_nodes_spec.rb +3 -4
  79. data/spec/notation/parsing/link_parsing_spec.rb +10 -4
  80. data/spec/notation/parsing/note_node_spec.rb +8 -7
  81. data/spec/notation/parsing/note_parsing_spec.rb +9 -12
  82. data/spec/performance/conversion/score_collator_spec.rb +14 -14
  83. data/spec/performance/midi/midi_util_spec.rb +26 -0
  84. data/spec/performance/midi/score_sequencer_spec.rb +1 -1
  85. metadata +57 -12
  86. data/lib/musicality/notation/model/program.rb +0 -53
  87. data/lib/musicality/notation/packing/program_packing.rb +0 -16
  88. data/spec/notation/model/program_spec.rb +0 -50
  89. data/spec/notation/packing/program_packing_spec.rb +0 -33
@@ -0,0 +1,22 @@
1
+ module Musicality
2
+
3
+ ARTICULATION_SYMBOLS = {
4
+ Articulations::SLUR => "(",
5
+ Articulations::LEGATO => "[",
6
+ Articulations::TENUTO => "_",
7
+ Articulations::PORTATO => "%",
8
+ Articulations::STACCATO => ".",
9
+ Articulations::STACCATISSIMO => "'"
10
+ }
11
+
12
+ LINK_SYMBOLS = {
13
+ Links::TIE => "=",
14
+ Links::GLISSANDO => "~",
15
+ Links::PORTAMENTO => "|",
16
+ Links::SLUR => ARTICULATION_SYMBOLS[Articulations::SLUR],
17
+ Links::LEGATO => ARTICULATION_SYMBOLS[Articulations::LEGATO],
18
+ }
19
+
20
+ ACCENT_SYMBOL = "!"
21
+
22
+ end
@@ -84,7 +84,7 @@ class Score
84
84
  [ name, part.pack ]
85
85
  end
86
86
  ]
87
- packed_prog = program.pack
87
+ packed_prog = @program.map {|seg| seg.to_s }
88
88
 
89
89
  { "type" => self.class.to_s.split("::")[-1],
90
90
  "program" => packed_prog,
@@ -96,8 +96,7 @@ class Score
96
96
  unpacked_parts = Hash[ packing["parts"].map do |name,packed|
97
97
  [name, Part.unpack(packed)]
98
98
  end ]
99
-
100
- unpacked_prog = Program.unpack packing["program"]
99
+ unpacked_prog = packing["program"].map {|str| Segment.parse(str) }
101
100
 
102
101
  new(program: unpacked_prog,
103
102
  parts: unpacked_parts
@@ -84,12 +84,12 @@ module Articulation
84
84
  return cached
85
85
  end
86
86
 
87
- if (match_len = has_terminal?("=", false, index))
87
+ if (match_len = has_terminal?("(", false, index))
88
88
  r0 = instantiate_node(SyntaxNode,input, index...(index + match_len))
89
89
  r0.extend(Slur0)
90
90
  @index += match_len
91
91
  else
92
- terminal_parse_failure("=")
92
+ terminal_parse_failure("(")
93
93
  r0 = nil
94
94
  end
95
95
 
@@ -115,12 +115,12 @@ module Articulation
115
115
  return cached
116
116
  end
117
117
 
118
- if (match_len = has_terminal?("|", false, index))
118
+ if (match_len = has_terminal?("[", false, index))
119
119
  r0 = instantiate_node(SyntaxNode,input, index...(index + match_len))
120
120
  r0.extend(Legato0)
121
121
  @index += match_len
122
122
  else
123
- terminal_parse_failure("|")
123
+ terminal_parse_failure("[")
124
124
  r0 = nil
125
125
  end
126
126
 
@@ -7,7 +7,7 @@ grammar Articulation
7
7
  end
8
8
 
9
9
  rule slur
10
- "=" {
10
+ "(" {
11
11
  def to_articulation
12
12
  Musicality::Articulations::SLUR
13
13
  end
@@ -15,7 +15,7 @@ grammar Articulation
15
15
  end
16
16
 
17
17
  rule legato
18
- "|" {
18
+ "[" {
19
19
  def to_articulation
20
20
  Musicality::Articulations::LEGATO
21
21
  end
@@ -1,28 +1,16 @@
1
1
  module Musicality
2
2
  module Parsing
3
3
  class LinkNode < Treetop::Runtime::SyntaxNode; end
4
-
5
- class SlurNode < LinkNode
6
- def to_link
7
- Musicality::Link::Slur.new(target.to_pitch)
8
- end
9
- end
10
-
11
- class LegatoNode < LinkNode
12
- def to_link
13
- Musicality::Link::Legato.new(target.to_pitch)
14
- end
15
- end
16
4
 
17
5
  class GlissandoNode < LinkNode
18
6
  def to_link
19
- Musicality::Link::Glissando.new(target.to_pitch)
7
+ Musicality::Link::Glissando.new(pitch.to_pitch)
20
8
  end
21
9
  end
22
10
 
23
11
  class PortamentoNode < LinkNode
24
12
  def to_link
25
- Musicality::Link::Portamento.new(target.to_pitch)
13
+ Musicality::Link::Portamento.new(pitch.to_pitch)
26
14
  end
27
15
  end
28
16
 
@@ -25,35 +25,23 @@ module Link
25
25
  end
26
26
 
27
27
  i0 = index
28
- r1 = _nt_slur_link
28
+ r1 = _nt_tie
29
29
  if r1
30
30
  r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
31
31
  r0 = r1
32
32
  else
33
- r2 = _nt_tie
33
+ r2 = _nt_glissando
34
34
  if r2
35
35
  r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
36
36
  r0 = r2
37
37
  else
38
- r3 = _nt_legato_link
38
+ r3 = _nt_portamento
39
39
  if r3
40
40
  r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
41
41
  r0 = r3
42
42
  else
43
- r4 = _nt_glissando
44
- if r4
45
- r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
46
- r0 = r4
47
- else
48
- r5 = _nt_portamento
49
- if r5
50
- r5 = SyntaxNode.new(input, (index-1)...index) if r5 == true
51
- r0 = r5
52
- else
53
- @index = i0
54
- r0 = nil
55
- end
56
- end
43
+ @index = i0
44
+ r0 = nil
57
45
  end
58
46
  end
59
47
  end
@@ -63,49 +51,6 @@ module Link
63
51
  r0
64
52
  end
65
53
 
66
- module SlurLink0
67
- def target
68
- elements[1]
69
- end
70
- end
71
-
72
- def _nt_slur_link
73
- start_index = index
74
- if node_cache[:slur_link].has_key?(index)
75
- cached = node_cache[:slur_link][index]
76
- if cached
77
- node_cache[:slur_link][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
78
- @index = cached.interval.end
79
- end
80
- return cached
81
- end
82
-
83
- i0, s0 = index, []
84
- if (match_len = has_terminal?("=", false, index))
85
- r1 = true
86
- @index += match_len
87
- else
88
- terminal_parse_failure("=")
89
- r1 = nil
90
- end
91
- s0 << r1
92
- if r1
93
- r2 = _nt_pitch
94
- s0 << r2
95
- end
96
- if s0.last
97
- r0 = instantiate_node(SlurNode,input, i0...index, s0)
98
- r0.extend(SlurLink0)
99
- else
100
- @index = i0
101
- r0 = nil
102
- end
103
-
104
- node_cache[:slur_link][start_index] = r0
105
-
106
- r0
107
- end
108
-
109
54
  def _nt_tie
110
55
  start_index = index
111
56
  if node_cache[:tie].has_key?(index)
@@ -130,51 +75,8 @@ module Link
130
75
  r0
131
76
  end
132
77
 
133
- module LegatoLink0
134
- def target
135
- elements[1]
136
- end
137
- end
138
-
139
- def _nt_legato_link
140
- start_index = index
141
- if node_cache[:legato_link].has_key?(index)
142
- cached = node_cache[:legato_link][index]
143
- if cached
144
- node_cache[:legato_link][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
145
- @index = cached.interval.end
146
- end
147
- return cached
148
- end
149
-
150
- i0, s0 = index, []
151
- if (match_len = has_terminal?("|", false, index))
152
- r1 = true
153
- @index += match_len
154
- else
155
- terminal_parse_failure("|")
156
- r1 = nil
157
- end
158
- s0 << r1
159
- if r1
160
- r2 = _nt_pitch
161
- s0 << r2
162
- end
163
- if s0.last
164
- r0 = instantiate_node(LegatoNode,input, i0...index, s0)
165
- r0.extend(LegatoLink0)
166
- else
167
- @index = i0
168
- r0 = nil
169
- end
170
-
171
- node_cache[:legato_link][start_index] = r0
172
-
173
- r0
174
- end
175
-
176
78
  module Glissando0
177
- def target
79
+ def pitch
178
80
  elements[1]
179
81
  end
180
82
  end
@@ -217,7 +119,7 @@ module Link
217
119
  end
218
120
 
219
121
  module Portamento0
220
- def target
122
+ def pitch
221
123
  elements[1]
222
124
  end
223
125
  end
@@ -234,11 +136,11 @@ module Link
234
136
  end
235
137
 
236
138
  i0, s0 = index, []
237
- if (match_len = has_terminal?("/", false, index))
139
+ if (match_len = has_terminal?("|", false, index))
238
140
  r1 = true
239
141
  @index += match_len
240
142
  else
241
- terminal_parse_failure("/")
143
+ terminal_parse_failure("|")
242
144
  r1 = nil
243
145
  end
244
146
  s0 << r1
@@ -3,29 +3,21 @@ module Parsing
3
3
 
4
4
  grammar Link
5
5
  include Pitch
6
-
6
+
7
7
  rule link
8
- slur_link / tie / legato_link / glissando / portamento
8
+ tie / glissando / portamento
9
9
  end
10
10
 
11
- rule slur_link
12
- "=" target:pitch <SlurNode>
13
- end
14
-
15
11
  rule tie
16
12
  "=" <TieNode>
17
13
  end
18
14
 
19
- rule legato_link
20
- "|" target:pitch <LegatoNode>
21
- end
22
-
23
15
  rule glissando
24
- "~" target:pitch <GlissandoNode>
16
+ "~" pitch <GlissandoNode>
25
17
  end
26
18
 
27
19
  rule portamento
28
- "/" target:pitch <PortamentoNode>
20
+ "|" pitch <PortamentoNode>
29
21
  end
30
22
  end
31
23
 
@@ -6,34 +6,36 @@ module Parsing
6
6
  end
7
7
 
8
8
  def to_note
9
+ if more.empty?
10
+ return Musicality::Note.new(duration.to_r)
11
+ end
12
+
9
13
  pitches = []
10
14
  links = {}
11
-
12
- unless pitch_links.empty?
13
- first = pitch_links.first
14
- more = pitch_links.more
15
-
16
- pitches.push first.pitch.to_pitch
17
- unless first.the_link.empty?
18
- links[pitches[-1]] = first.the_link.to_link
19
- end
20
-
21
- more.elements.each do |x|
22
- pitches.push x.pl.pitch.to_pitch
23
- unless x.pl.the_link.empty?
24
- links[pitches[-1]] = x.pl.the_link.to_link
25
- end
15
+
16
+ first_pl = more.first_pl
17
+ more_pl = more.more_pl
18
+
19
+ pitches.push first_pl.pitch.to_pitch
20
+ unless first_pl.the_link.empty?
21
+ links[pitches[-1]] = first_pl.the_link.to_link
22
+ end
23
+
24
+ more_pl.elements.each do |x|
25
+ pitches.push x.pl.pitch.to_pitch
26
+ unless x.pl.the_link.empty?
27
+ links[pitches[-1]] = x.pl.the_link.to_link
26
28
  end
27
29
  end
28
30
 
29
31
  artic = Musicality::Articulations::NORMAL
30
- unless art.empty?
31
- artic = art.to_articulation
32
+ unless more.art.empty?
33
+ artic = more.art.to_articulation
32
34
  end
33
-
34
- accent_flag = acc.empty? ? false : true
35
- Musicality::Note.new(duration.to_r,
36
- pitches, links: links, articulation: artic, accented: accent_flag)
35
+
36
+ accent_flag = !more.acc.empty?
37
+ Musicality::Note.new(duration.to_r, pitches,
38
+ links: links, articulation: artic, accented: accent_flag)
37
39
  end
38
40
  end
39
41
  end
@@ -26,13 +26,21 @@ module Note
26
26
  end
27
27
 
28
28
  module Note1
29
- def first
29
+ def first_pl
30
30
  elements[0]
31
31
  end
32
32
 
33
- def more
33
+ def more_pl
34
34
  elements[1]
35
35
  end
36
+
37
+ def art
38
+ elements[2]
39
+ end
40
+
41
+ def acc
42
+ elements[3]
43
+ end
36
44
  end
37
45
 
38
46
  module Note2
@@ -40,17 +48,9 @@ module Note
40
48
  elements[0]
41
49
  end
42
50
 
43
- def art
51
+ def more
44
52
  elements[1]
45
53
  end
46
-
47
- def pitch_links
48
- elements[2]
49
- end
50
-
51
- def acc
52
- elements[3]
53
- end
54
54
  end
55
55
 
56
56
  def _nt_note
@@ -68,72 +68,72 @@ module Note
68
68
  r1 = _nt_duration
69
69
  s0 << r1
70
70
  if r1
71
- r3 = _nt_articulation
72
- if r3
73
- r2 = r3
74
- else
75
- r2 = instantiate_node(SyntaxNode,input, index...index)
76
- end
77
- s0 << r2
78
- if r2
79
- i5, s5 = index, []
80
- r6 = _nt_pitch_link
81
- s5 << r6
82
- if r6
83
- s7, i7 = [], index
84
- loop do
85
- i8, s8 = index, []
86
- if (match_len = has_terminal?(",", false, index))
87
- r9 = true
88
- @index += match_len
89
- else
90
- terminal_parse_failure(",")
91
- r9 = nil
92
- end
93
- s8 << r9
94
- if r9
95
- r10 = _nt_pitch_link
96
- s8 << r10
97
- end
98
- if s8.last
99
- r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
100
- r8.extend(Note0)
101
- else
102
- @index = i8
103
- r8 = nil
104
- end
105
- if r8
106
- s7 << r8
107
- else
108
- break
109
- end
71
+ i3, s3 = index, []
72
+ r4 = _nt_pitch_link
73
+ s3 << r4
74
+ if r4
75
+ s5, i5 = [], index
76
+ loop do
77
+ i6, s6 = index, []
78
+ if (match_len = has_terminal?(",", false, index))
79
+ r7 = true
80
+ @index += match_len
81
+ else
82
+ terminal_parse_failure(",")
83
+ r7 = nil
84
+ end
85
+ s6 << r7
86
+ if r7
87
+ r8 = _nt_pitch_link
88
+ s6 << r8
89
+ end
90
+ if s6.last
91
+ r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
92
+ r6.extend(Note0)
93
+ else
94
+ @index = i6
95
+ r6 = nil
96
+ end
97
+ if r6
98
+ s5 << r6
99
+ else
100
+ break
110
101
  end
111
- r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
112
- s5 << r7
113
- end
114
- if s5.last
115
- r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
116
- r5.extend(Note1)
117
- else
118
- @index = i5
119
- r5 = nil
120
102
  end
103
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
104
+ s3 << r5
121
105
  if r5
122
- r4 = r5
123
- else
124
- r4 = instantiate_node(SyntaxNode,input, index...index)
125
- end
126
- s0 << r4
127
- if r4
128
- r12 = _nt_accent
129
- if r12
130
- r11 = r12
106
+ r10 = _nt_articulation
107
+ if r10
108
+ r9 = r10
131
109
  else
132
- r11 = instantiate_node(SyntaxNode,input, index...index)
110
+ r9 = instantiate_node(SyntaxNode,input, index...index)
111
+ end
112
+ s3 << r9
113
+ if r9
114
+ r12 = _nt_accent
115
+ if r12
116
+ r11 = r12
117
+ else
118
+ r11 = instantiate_node(SyntaxNode,input, index...index)
119
+ end
120
+ s3 << r11
133
121
  end
134
- s0 << r11
135
122
  end
136
123
  end
124
+ if s3.last
125
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
126
+ r3.extend(Note1)
127
+ else
128
+ @index = i3
129
+ r3 = nil
130
+ end
131
+ if r3
132
+ r2 = r3
133
+ else
134
+ r2 = instantiate_node(SyntaxNode,input, index...index)
135
+ end
136
+ s0 << r2
137
137
  end
138
138
  if s0.last
139
139
  r0 = instantiate_node(NoteNode,input, i0...index, s0)