musicality 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog.md +8 -1
- data/bin/midify +3 -4
- data/examples/composition/auto_counterpoint.rb +53 -0
- data/examples/composition/part_generator.rb +51 -0
- data/examples/composition/scale_exercise.rb +41 -0
- data/examples/{hip.rb → notation/hip.rb} +1 -1
- data/examples/{missed_connection.rb → notation/missed_connection.rb} +1 -1
- data/examples/{song1.rb → notation/song1.rb} +1 -1
- data/examples/{song2.rb → notation/song2.rb} +1 -1
- data/lib/musicality.rb +34 -4
- data/lib/musicality/composition/generation/counterpoint_generator.rb +153 -0
- data/lib/musicality/composition/generation/random_rhythm_generator.rb +39 -0
- data/lib/musicality/composition/model/pitch_class.rb +33 -0
- data/lib/musicality/composition/model/pitch_classes.rb +22 -0
- data/lib/musicality/composition/model/scale.rb +34 -0
- data/lib/musicality/composition/model/scale_class.rb +37 -0
- data/lib/musicality/composition/model/scale_classes.rb +91 -0
- data/lib/musicality/composition/note_generation.rb +31 -0
- data/lib/musicality/composition/transposition.rb +8 -0
- data/lib/musicality/composition/util/adding_sequence.rb +24 -0
- data/lib/musicality/composition/util/biinfinite_sequence.rb +130 -0
- data/lib/musicality/composition/util/compound_sequence.rb +44 -0
- data/lib/musicality/composition/util/probabilities.rb +20 -0
- data/lib/musicality/composition/util/random_sampler.rb +26 -0
- data/lib/musicality/composition/util/repeating_sequence.rb +24 -0
- data/lib/musicality/errors.rb +2 -0
- data/lib/musicality/notation/conversion/score_conversion.rb +1 -1
- data/lib/musicality/notation/conversion/score_converter.rb +3 -3
- data/lib/musicality/notation/model/link.rb +26 -24
- data/lib/musicality/notation/model/links.rb +11 -0
- data/lib/musicality/notation/model/note.rb +14 -15
- data/lib/musicality/notation/model/part.rb +3 -3
- data/lib/musicality/notation/model/pitch.rb +8 -0
- data/lib/musicality/notation/model/score.rb +70 -44
- data/lib/musicality/notation/model/symbols.rb +22 -0
- data/lib/musicality/notation/packing/score_packing.rb +2 -3
- data/lib/musicality/notation/parsing/articulation_parsing.rb +4 -4
- data/lib/musicality/notation/parsing/articulation_parsing.treetop +2 -2
- data/lib/musicality/notation/parsing/link_nodes.rb +2 -14
- data/lib/musicality/notation/parsing/link_parsing.rb +9 -107
- data/lib/musicality/notation/parsing/link_parsing.treetop +4 -12
- data/lib/musicality/notation/parsing/note_node.rb +23 -21
- data/lib/musicality/notation/parsing/note_parsing.rb +70 -70
- data/lib/musicality/notation/parsing/note_parsing.treetop +6 -3
- data/lib/musicality/notation/parsing/pitch_node.rb +4 -2
- data/lib/musicality/performance/conversion/score_collator.rb +3 -3
- data/lib/musicality/performance/midi/midi_util.rb +13 -6
- data/lib/musicality/performance/midi/score_sequencing.rb +17 -0
- data/lib/musicality/printing/lilypond/errors.rb +5 -0
- data/lib/musicality/printing/lilypond/meter_engraving.rb +11 -0
- data/lib/musicality/printing/lilypond/note_engraving.rb +53 -0
- data/lib/musicality/printing/lilypond/part_engraver.rb +12 -0
- data/lib/musicality/printing/lilypond/pitch_engraving.rb +30 -0
- data/lib/musicality/printing/lilypond/score_engraver.rb +78 -0
- data/lib/musicality/version.rb +1 -1
- data/spec/composition/generation/random_rhythm_generator_spec.rb +50 -0
- data/spec/composition/model/pitch_class_spec.rb +75 -0
- data/spec/composition/model/pitch_classes_spec.rb +24 -0
- data/spec/composition/model/scale_class_spec.rb +98 -0
- data/spec/composition/model/scale_spec.rb +110 -0
- data/spec/composition/note_generation_spec.rb +113 -0
- data/spec/composition/transposition_spec.rb +17 -0
- data/spec/composition/util/adding_sequence_spec.rb +176 -0
- data/spec/composition/util/compound_sequence_spec.rb +50 -0
- data/spec/composition/util/probabilities_spec.rb +39 -0
- data/spec/composition/util/random_sampler_spec.rb +47 -0
- data/spec/composition/util/repeating_sequence_spec.rb +151 -0
- data/spec/notation/conversion/score_conversion_spec.rb +3 -3
- data/spec/notation/conversion/score_converter_spec.rb +24 -24
- data/spec/notation/model/link_spec.rb +27 -25
- data/spec/notation/model/note_spec.rb +9 -6
- data/spec/notation/model/pitch_spec.rb +24 -1
- data/spec/notation/model/score_spec.rb +57 -16
- data/spec/notation/packing/score_packing_spec.rb +134 -206
- data/spec/notation/parsing/articulation_parsing_spec.rb +1 -8
- data/spec/notation/parsing/convenience_methods_spec.rb +1 -1
- data/spec/notation/parsing/link_nodes_spec.rb +3 -4
- data/spec/notation/parsing/link_parsing_spec.rb +10 -4
- data/spec/notation/parsing/note_node_spec.rb +8 -7
- data/spec/notation/parsing/note_parsing_spec.rb +9 -12
- data/spec/performance/conversion/score_collator_spec.rb +14 -14
- data/spec/performance/midi/midi_util_spec.rb +26 -0
- data/spec/performance/midi/score_sequencer_spec.rb +1 -1
- metadata +57 -12
- data/lib/musicality/notation/model/program.rb +0 -53
- data/lib/musicality/notation/packing/program_packing.rb +0 -16
- data/spec/notation/model/program_spec.rb +0 -50
- data/spec/notation/packing/program_packing_spec.rb +0 -33
@@ -3,14 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
3
3
|
describe Parsing::ArticulationParser do
|
4
4
|
parser = Parsing::ArticulationParser.new
|
5
5
|
|
6
|
-
|
7
|
-
'=' => SLUR,
|
8
|
-
'|' => LEGATO,
|
9
|
-
'_' => TENUTO,
|
10
|
-
'%' => PORTATO,
|
11
|
-
'.' => STACCATO,
|
12
|
-
"'" => STACCATISSIMO
|
13
|
-
}.each do |str,art|
|
6
|
+
ARTICULATION_SYMBOLS.each do |art,str|
|
14
7
|
res = parser.parse(str)
|
15
8
|
it "should parse '#{str}'" do
|
16
9
|
res.should_not be nil
|
@@ -9,7 +9,7 @@ class_cases = { Duration => {
|
|
9
9
|
Note => {
|
10
10
|
'/2' => Note::half,
|
11
11
|
'99/10C2' => Note.new('99/10'.to_r, [C2]),
|
12
|
-
'5/
|
12
|
+
'5/2Db4,Eb5.' => Note.new('5/2'.to_r, [Db4,Eb5], articulation:STACCATO)
|
13
13
|
},
|
14
14
|
Pitch => {
|
15
15
|
'C2' => C2,
|
@@ -4,10 +4,9 @@ describe Parsing::LinkNode do
|
|
4
4
|
parser = Parsing::LinkParser.new
|
5
5
|
|
6
6
|
{
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
'|Db2' => Link::Legato.new(Db2),
|
7
|
+
LINK_SYMBOLS[Links::TIE] => Link::Tie.new,
|
8
|
+
(LINK_SYMBOLS[Links::GLISSANDO] + Db2.to_s) => Link::Glissando.new(Db2),
|
9
|
+
(LINK_SYMBOLS[Links::PORTAMENTO] + Db2.to_s) => Link::Portamento.new(Db2),
|
11
10
|
}.each do |str,tgt|
|
12
11
|
res = parser.parse(str)
|
13
12
|
context str do
|
@@ -5,9 +5,15 @@ describe Parsing::LinkParser do
|
|
5
5
|
@parser = Parsing::LinkParser.new
|
6
6
|
end
|
7
7
|
|
8
|
-
["
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
it "should parse #{LINK_SYMBOLS[Links::TIE]}" do
|
9
|
+
@parser.should parse(LINK_SYMBOLS[Links::TIE])
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should parse #{LINK_SYMBOLS[Links::GLISSANDO]} with target pitch" do
|
13
|
+
@parser.should parse(LINK_SYMBOLS[Links::GLISSANDO] + C3.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should parse #{LINK_SYMBOLS[Links::PORTAMENTO]} with target pitch" do
|
17
|
+
@parser.should parse(LINK_SYMBOLS[Links::GLISSANDO] + C3.to_s)
|
12
18
|
end
|
13
19
|
end
|
@@ -32,10 +32,10 @@ describe Parsing::NoteNode do
|
|
32
32
|
|
33
33
|
context 'monophonic note' do
|
34
34
|
{
|
35
|
-
'/
|
36
|
-
'4/
|
37
|
-
'
|
38
|
-
"56/
|
35
|
+
'/2C2=' => Note.new(Rational(1,2),[C2], links: { C2 => Link::Tie.new}),
|
36
|
+
'4/2D#6.' => Note.new(Rational(4,2),[Eb6],articulation:STACCATO),
|
37
|
+
'28Eb7%!' => Note.new(Rational(28,1),[Eb7],articulation:PORTATO, accented: true),
|
38
|
+
"56/33B1'" => Note.new(Rational(56,33),[B1],articulation:STACCATISSIMO),
|
39
39
|
}.each do |str,tgt|
|
40
40
|
res = NOTE_PARSER.parse(str)
|
41
41
|
|
@@ -60,9 +60,10 @@ describe Parsing::NoteNode do
|
|
60
60
|
|
61
61
|
context 'polyphonic note' do
|
62
62
|
{
|
63
|
-
'/2C2,D2,E2
|
64
|
-
'
|
65
|
-
'
|
63
|
+
'/2C2,D2,E2(' => Note.new(Rational(1,2),[C2,D2,E2],articulation: Articulations::SLUR),
|
64
|
+
'/2C2,D2,E2[' => Note.new(Rational(1,2),[C2,D2,E2],articulation: Articulations::LEGATO),
|
65
|
+
'4/2D#6,G4.' => Note.new(Rational(4,2),[Eb6,G4], articulation: Articulations::STACCATO),
|
66
|
+
'28Eb7,D7,G7_' => Note.new(Rational(28,1),[Eb7,D7,G7],articulation: Articulations::TENUTO),
|
66
67
|
'56/33B1,B2,B3,B4,B5!' => Note.new(Rational(56,33),[B1,B2,B3,B4,B5], accented: true),
|
67
68
|
}.each do |str,tgt|
|
68
69
|
res = NOTE_PARSER.parse(str)
|
@@ -7,25 +7,22 @@ describe Parsing::NoteParser do
|
|
7
7
|
|
8
8
|
valid_cases = {
|
9
9
|
'duration only' => ['1/4','/2','1','55/33'],
|
10
|
-
'duration + accent' => ['1/4!','/2!'],
|
11
|
-
'duration + articulation' => ['1/4.','/2%','2/3='],
|
12
|
-
'duration + articulation + accent' => ['1/4.!','/2%!','2/3=!'],
|
13
10
|
'single pitch' => ['/4C2','5/3Db3','/33E#8'],
|
14
11
|
'multiple pitches' => ['/4C2,C3,c5','5/3Db3,Bb2,E5','/33E#8,F1,B9'],
|
15
|
-
'with articulation' => ['/
|
12
|
+
'with articulation' => ['/4C2.',"5/3Db3,Bb2,E5'",'/33F3(','/2D3,F4_'],
|
16
13
|
'with accent' => ['/4C2!','3/2Db3,Bb4!'],
|
17
|
-
'with links' => ['/2C2=','/2C2
|
14
|
+
'with links' => ['/2C2=','/2C2|D2','/4D4|E4,G4~A5.'],
|
18
15
|
'with single pitch + articulation + link + accent' => [
|
19
|
-
'3/
|
16
|
+
'3/4D2=(!','5/8F2~G2.!','/8Db4|Db5!','/3G4~B4_!'],
|
20
17
|
'with multiple pitches + articulation + links + accent' => [
|
21
|
-
'5/
|
18
|
+
'5/4D2=,G4|A4,C3~D3.!','5/8F2=,B4|A4_!'],
|
22
19
|
}
|
23
20
|
invalid_cases = {
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'with
|
28
|
-
'
|
21
|
+
'duration + accent' => ['1/4!','/2!'],
|
22
|
+
'duration + articulation' => ['1/4.','/2%','2/3('],
|
23
|
+
'duration + accent + link' => ['1/4!~','/2!/','2/3=!'],
|
24
|
+
'single pith with bad letter' => ['5/3Hb3'],
|
25
|
+
'single pitch without octave' => ['/33E(2'],
|
29
26
|
}
|
30
27
|
|
31
28
|
valid_cases.each do |descr, strs|
|
@@ -15,7 +15,7 @@ describe ScoreCollator do
|
|
15
15
|
it 'should not be included in the part' do
|
16
16
|
score = Score::Measured.new(FOUR_FOUR, 120,
|
17
17
|
parts: {1 => @part},
|
18
|
-
program:
|
18
|
+
program: ["1/4".to_r..."5/4".to_r])
|
19
19
|
collator = ScoreCollator.new(score)
|
20
20
|
parts = collator.collate_parts
|
21
21
|
notes = parts[1].notes
|
@@ -29,7 +29,7 @@ describe ScoreCollator do
|
|
29
29
|
it 'should not be included in the part, and a rest is inserted' do
|
30
30
|
score = Score::Measured.new(FOUR_FOUR, 120,
|
31
31
|
parts: {1 => @part},
|
32
|
-
program:
|
32
|
+
program: ["1/8".to_r..."5/4".to_r])
|
33
33
|
collator = ScoreCollator.new(score)
|
34
34
|
parts = collator.collate_parts
|
35
35
|
notes = parts[1].notes
|
@@ -47,7 +47,7 @@ describe ScoreCollator do
|
|
47
47
|
it 'should not be included in the part' do
|
48
48
|
score = Score::Measured.new(FOUR_FOUR, 120,
|
49
49
|
parts: {1 => @part},
|
50
|
-
program:
|
50
|
+
program: [0.to_r..."3/4".to_r])
|
51
51
|
collator = ScoreCollator.new(score)
|
52
52
|
parts = collator.collate_parts
|
53
53
|
notes = parts[1].notes
|
@@ -59,7 +59,7 @@ describe ScoreCollator do
|
|
59
59
|
it 'should be included in the part, but truncated' do
|
60
60
|
score = Score::Measured.new(FOUR_FOUR, 120,
|
61
61
|
parts: {1 => @part},
|
62
|
-
program:
|
62
|
+
program: [0.to_r...1.to_r])
|
63
63
|
collator = ScoreCollator.new(score)
|
64
64
|
parts = collator.collate_parts
|
65
65
|
notes = parts[1].notes
|
@@ -72,7 +72,7 @@ describe ScoreCollator do
|
|
72
72
|
it 'should insert a rest between last note end and segment end' do
|
73
73
|
score = Score::Measured.new(FOUR_FOUR, 120,
|
74
74
|
parts: {1 => @part},
|
75
|
-
program:
|
75
|
+
program: [0.to_r..."6/4".to_r])
|
76
76
|
collator = ScoreCollator.new(score)
|
77
77
|
parts = collator.collate_parts
|
78
78
|
notes = parts[1].notes
|
@@ -89,7 +89,7 @@ describe ScoreCollator do
|
|
89
89
|
parts: { 1 => Part.new(Dynamics::FF, dynamic_changes: {
|
90
90
|
2 => Change::Gradual.linear(Dynamics::PP,5).trim(1,0)
|
91
91
|
}) },
|
92
|
-
program:
|
92
|
+
program: [7...9]
|
93
93
|
)
|
94
94
|
collator = ScoreCollator.new(score)
|
95
95
|
parts = collator.collate_parts
|
@@ -97,7 +97,7 @@ describe ScoreCollator do
|
|
97
97
|
dcs.size.should eq(1)
|
98
98
|
dcs[0.to_r].should eq(Change::Immediate.new(Dynamics::PP))
|
99
99
|
|
100
|
-
score.program =
|
100
|
+
score.program = [0...1]
|
101
101
|
collator = ScoreCollator.new(score)
|
102
102
|
parts = collator.collate_parts
|
103
103
|
dcs = parts[1].dynamic_changes
|
@@ -110,7 +110,7 @@ describe ScoreCollator do
|
|
110
110
|
parts: { 1 => Part.new(Dynamics::FF, dynamic_changes: {
|
111
111
|
2 => Change::Gradual.linear(Dynamics::PP,5).trim(1,1)
|
112
112
|
}) },
|
113
|
-
program:
|
113
|
+
program: [3...4]
|
114
114
|
)
|
115
115
|
collator = ScoreCollator.new(score)
|
116
116
|
parts = collator.collate_parts
|
@@ -125,7 +125,7 @@ describe ScoreCollator do
|
|
125
125
|
score = Score::Measured.new(
|
126
126
|
FOUR_FOUR,120,
|
127
127
|
parts: { "lead" => Part.new(Dynamics::MP, notes: notes) },
|
128
|
-
program:
|
128
|
+
program: [0..1,0..1],
|
129
129
|
)
|
130
130
|
collator = ScoreCollator.new(score)
|
131
131
|
parts = collator.collate_parts
|
@@ -149,7 +149,7 @@ describe ScoreCollator do
|
|
149
149
|
context 'tempo change starts at end of program segment' do
|
150
150
|
it 'should not be included in the tempo changes' do
|
151
151
|
score = Score::Measured.new(FOUR_FOUR, 120, tempo_changes: {
|
152
|
-
1 => @change1, 2 => @change2 }, program:
|
152
|
+
1 => @change1, 2 => @change2 }, program: [0..2])
|
153
153
|
collator = ScoreCollator.new(score)
|
154
154
|
tcs = collator.collate_tempo_changes
|
155
155
|
tcs.size.should eq 2
|
@@ -161,7 +161,7 @@ describe ScoreCollator do
|
|
161
161
|
context 'tempo change starts and ends before segment' do
|
162
162
|
before :all do
|
163
163
|
score = Score::Measured.new(FOUR_FOUR, 120, tempo_changes: {
|
164
|
-
2 => @change2 }, program:
|
164
|
+
2 => @change2 }, program: [4..5])
|
165
165
|
collator = ScoreCollator.new(score)
|
166
166
|
@tcs = collator.collate_tempo_changes
|
167
167
|
end
|
@@ -179,7 +179,7 @@ describe ScoreCollator do
|
|
179
179
|
context 'tempo change starts before segment, but ends during segment' do
|
180
180
|
it 'should e included in the tempo changes, but truncated' do
|
181
181
|
score = Score::Measured.new(FOUR_FOUR, 120, tempo_changes: {
|
182
|
-
1.5.to_r => @change2 }, program:
|
182
|
+
1.5.to_r => @change2 }, program: [2..4])
|
183
183
|
collator = ScoreCollator.new(score)
|
184
184
|
tcs = collator.collate_tempo_changes
|
185
185
|
tcs.size.should eq 1
|
@@ -192,7 +192,7 @@ describe ScoreCollator do
|
|
192
192
|
context 'tempo change starts during segment, lasts until after' do
|
193
193
|
it 'should be included in the tempo changes, but truncated' do
|
194
194
|
score = Score::Measured.new(FOUR_FOUR, 120, tempo_changes: {
|
195
|
-
1 => @change1, 2 => @change2 }, program:
|
195
|
+
1 => @change1, 2 => @change2 }, program: [0..2.5])
|
196
196
|
collator = ScoreCollator.new(score)
|
197
197
|
tcs = collator.collate_tempo_changes
|
198
198
|
tcs.size.should eq 3
|
@@ -211,7 +211,7 @@ describe ScoreCollator do
|
|
211
211
|
change1 = Change::Immediate.new(THREE_FOUR)
|
212
212
|
change2 = Change::Immediate.new(SIX_EIGHT)
|
213
213
|
score = Score::Measured.new(FOUR_FOUR, 120, meter_changes: {
|
214
|
-
1 => change1, 2 => change2 }, program:
|
214
|
+
1 => change1, 2 => change2 }, program: [0...2])
|
215
215
|
collator = ScoreCollator.new(score)
|
216
216
|
tcs = collator.collate_meter_changes
|
217
217
|
tcs.size.should eq 2
|
@@ -43,6 +43,32 @@ describe MidiUtil do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
describe '.notenum_to_pitch' do
|
48
|
+
context 'given 60' do
|
49
|
+
it 'should return C4' do
|
50
|
+
MidiUtil.notenum_to_pitch(60).should eq(C4)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'given 69' do
|
55
|
+
it 'should return A4' do
|
56
|
+
MidiUtil.notenum_to_pitch(69).should eq(A4)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'given 0' do
|
61
|
+
it 'should return octave below C0' do
|
62
|
+
MidiUtil.notenum_to_pitch(0).should eq(Pitch.new(octave:-1))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'given 127' do
|
67
|
+
it 'should return G9' do
|
68
|
+
MidiUtil.notenum_to_pitch(127).should eq(G9)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
46
72
|
|
47
73
|
describe '.dynamic_to_volume' do
|
48
74
|
context 'given 0' do
|
@@ -10,7 +10,7 @@ describe ScoreSequencer do
|
|
10
10
|
@part2_name = "def"
|
11
11
|
@part1 = Part.new(Dynamics::PP, notes: "/4C4 /4D4 /8 /8D4 /8E4 3/8C4".to_notes * 2)
|
12
12
|
@part2 = Part.new(Dynamics::FF, notes: "/4E4 3/4F4 /4E4".to_notes * 2)
|
13
|
-
@score = Score::Timed.new(program:
|
13
|
+
@score = Score::Timed.new(program: [0..2.5],
|
14
14
|
parts: {@part1_name => @part2, @part2_name => @part2})
|
15
15
|
@instr_map = {@part1_name => 33, @part2_name => 25}
|
16
16
|
@midi_seq = ScoreSequencer.new(@score).make_midi_seq(@instr_map)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: musicality
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Tunnell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,11 +129,29 @@ files:
|
|
129
129
|
- README.md
|
130
130
|
- Rakefile
|
131
131
|
- bin/midify
|
132
|
-
- examples/
|
133
|
-
- examples/
|
134
|
-
- examples/
|
135
|
-
- examples/
|
132
|
+
- examples/composition/auto_counterpoint.rb
|
133
|
+
- examples/composition/part_generator.rb
|
134
|
+
- examples/composition/scale_exercise.rb
|
135
|
+
- examples/notation/hip.rb
|
136
|
+
- examples/notation/missed_connection.rb
|
137
|
+
- examples/notation/song1.rb
|
138
|
+
- examples/notation/song2.rb
|
136
139
|
- lib/musicality.rb
|
140
|
+
- lib/musicality/composition/generation/counterpoint_generator.rb
|
141
|
+
- lib/musicality/composition/generation/random_rhythm_generator.rb
|
142
|
+
- lib/musicality/composition/model/pitch_class.rb
|
143
|
+
- lib/musicality/composition/model/pitch_classes.rb
|
144
|
+
- lib/musicality/composition/model/scale.rb
|
145
|
+
- lib/musicality/composition/model/scale_class.rb
|
146
|
+
- lib/musicality/composition/model/scale_classes.rb
|
147
|
+
- lib/musicality/composition/note_generation.rb
|
148
|
+
- lib/musicality/composition/transposition.rb
|
149
|
+
- lib/musicality/composition/util/adding_sequence.rb
|
150
|
+
- lib/musicality/composition/util/biinfinite_sequence.rb
|
151
|
+
- lib/musicality/composition/util/compound_sequence.rb
|
152
|
+
- lib/musicality/composition/util/probabilities.rb
|
153
|
+
- lib/musicality/composition/util/random_sampler.rb
|
154
|
+
- lib/musicality/composition/util/repeating_sequence.rb
|
137
155
|
- lib/musicality/errors.rb
|
138
156
|
- lib/musicality/notation/conversion/change_conversion.rb
|
139
157
|
- lib/musicality/notation/conversion/measure_note_map.rb
|
@@ -145,17 +163,17 @@ files:
|
|
145
163
|
- lib/musicality/notation/model/change.rb
|
146
164
|
- lib/musicality/notation/model/dynamics.rb
|
147
165
|
- lib/musicality/notation/model/link.rb
|
166
|
+
- lib/musicality/notation/model/links.rb
|
148
167
|
- lib/musicality/notation/model/meter.rb
|
149
168
|
- lib/musicality/notation/model/meters.rb
|
150
169
|
- lib/musicality/notation/model/note.rb
|
151
170
|
- lib/musicality/notation/model/part.rb
|
152
171
|
- lib/musicality/notation/model/pitch.rb
|
153
172
|
- lib/musicality/notation/model/pitches.rb
|
154
|
-
- lib/musicality/notation/model/program.rb
|
155
173
|
- lib/musicality/notation/model/score.rb
|
174
|
+
- lib/musicality/notation/model/symbols.rb
|
156
175
|
- lib/musicality/notation/packing/change_packing.rb
|
157
176
|
- lib/musicality/notation/packing/part_packing.rb
|
158
|
-
- lib/musicality/notation/packing/program_packing.rb
|
159
177
|
- lib/musicality/notation/packing/score_packing.rb
|
160
178
|
- lib/musicality/notation/parsing/articulation_parsing.rb
|
161
179
|
- lib/musicality/notation/parsing/articulation_parsing.treetop
|
@@ -202,13 +220,32 @@ files:
|
|
202
220
|
- lib/musicality/performance/midi/midi_util.rb
|
203
221
|
- lib/musicality/performance/midi/part_sequencer.rb
|
204
222
|
- lib/musicality/performance/midi/score_sequencer.rb
|
223
|
+
- lib/musicality/performance/midi/score_sequencing.rb
|
205
224
|
- lib/musicality/performance/model/note_attacks.rb
|
206
225
|
- lib/musicality/performance/model/note_sequence.rb
|
207
226
|
- lib/musicality/performance/util/note_linker.rb
|
208
227
|
- lib/musicality/performance/util/optimization.rb
|
228
|
+
- lib/musicality/printing/lilypond/errors.rb
|
229
|
+
- lib/musicality/printing/lilypond/meter_engraving.rb
|
230
|
+
- lib/musicality/printing/lilypond/note_engraving.rb
|
231
|
+
- lib/musicality/printing/lilypond/part_engraver.rb
|
232
|
+
- lib/musicality/printing/lilypond/pitch_engraving.rb
|
233
|
+
- lib/musicality/printing/lilypond/score_engraver.rb
|
209
234
|
- lib/musicality/validatable.rb
|
210
235
|
- lib/musicality/version.rb
|
211
236
|
- musicality.gemspec
|
237
|
+
- spec/composition/generation/random_rhythm_generator_spec.rb
|
238
|
+
- spec/composition/model/pitch_class_spec.rb
|
239
|
+
- spec/composition/model/pitch_classes_spec.rb
|
240
|
+
- spec/composition/model/scale_class_spec.rb
|
241
|
+
- spec/composition/model/scale_spec.rb
|
242
|
+
- spec/composition/note_generation_spec.rb
|
243
|
+
- spec/composition/transposition_spec.rb
|
244
|
+
- spec/composition/util/adding_sequence_spec.rb
|
245
|
+
- spec/composition/util/compound_sequence_spec.rb
|
246
|
+
- spec/composition/util/probabilities_spec.rb
|
247
|
+
- spec/composition/util/random_sampler_spec.rb
|
248
|
+
- spec/composition/util/repeating_sequence_spec.rb
|
212
249
|
- spec/musicality_spec.rb
|
213
250
|
- spec/notation/conversion/change_conversion_spec.rb
|
214
251
|
- spec/notation/conversion/measure_note_map_spec.rb
|
@@ -222,11 +259,9 @@ files:
|
|
222
259
|
- spec/notation/model/note_spec.rb
|
223
260
|
- spec/notation/model/part_spec.rb
|
224
261
|
- spec/notation/model/pitch_spec.rb
|
225
|
-
- spec/notation/model/program_spec.rb
|
226
262
|
- spec/notation/model/score_spec.rb
|
227
263
|
- spec/notation/packing/change_packing_spec.rb
|
228
264
|
- spec/notation/packing/part_packing_spec.rb
|
229
|
-
- spec/notation/packing/program_packing_spec.rb
|
230
265
|
- spec/notation/packing/score_packing_spec.rb
|
231
266
|
- spec/notation/parsing/articulation_parsing_spec.rb
|
232
267
|
- spec/notation/parsing/convenience_methods_spec.rb
|
@@ -285,6 +320,18 @@ signing_key:
|
|
285
320
|
specification_version: 4
|
286
321
|
summary: Music notation, composition, and performance
|
287
322
|
test_files:
|
323
|
+
- spec/composition/generation/random_rhythm_generator_spec.rb
|
324
|
+
- spec/composition/model/pitch_class_spec.rb
|
325
|
+
- spec/composition/model/pitch_classes_spec.rb
|
326
|
+
- spec/composition/model/scale_class_spec.rb
|
327
|
+
- spec/composition/model/scale_spec.rb
|
328
|
+
- spec/composition/note_generation_spec.rb
|
329
|
+
- spec/composition/transposition_spec.rb
|
330
|
+
- spec/composition/util/adding_sequence_spec.rb
|
331
|
+
- spec/composition/util/compound_sequence_spec.rb
|
332
|
+
- spec/composition/util/probabilities_spec.rb
|
333
|
+
- spec/composition/util/random_sampler_spec.rb
|
334
|
+
- spec/composition/util/repeating_sequence_spec.rb
|
288
335
|
- spec/musicality_spec.rb
|
289
336
|
- spec/notation/conversion/change_conversion_spec.rb
|
290
337
|
- spec/notation/conversion/measure_note_map_spec.rb
|
@@ -298,11 +345,9 @@ test_files:
|
|
298
345
|
- spec/notation/model/note_spec.rb
|
299
346
|
- spec/notation/model/part_spec.rb
|
300
347
|
- spec/notation/model/pitch_spec.rb
|
301
|
-
- spec/notation/model/program_spec.rb
|
302
348
|
- spec/notation/model/score_spec.rb
|
303
349
|
- spec/notation/packing/change_packing_spec.rb
|
304
350
|
- spec/notation/packing/part_packing_spec.rb
|
305
|
-
- spec/notation/packing/program_packing_spec.rb
|
306
351
|
- spec/notation/packing/score_packing_spec.rb
|
307
352
|
- spec/notation/parsing/articulation_parsing_spec.rb
|
308
353
|
- spec/notation/parsing/convenience_methods_spec.rb
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module Musicality
|
2
|
-
|
3
|
-
# Program defines markers (by starting note offset) and subprograms (list which markers are played).
|
4
|
-
#
|
5
|
-
# @author James Tunnell
|
6
|
-
#
|
7
|
-
class Program
|
8
|
-
include Validatable
|
9
|
-
|
10
|
-
attr_accessor :segments
|
11
|
-
|
12
|
-
def initialize segments = []
|
13
|
-
@segments = segments
|
14
|
-
end
|
15
|
-
|
16
|
-
def check_methods
|
17
|
-
[:ensure_increasing_segments, :ensure_nonnegative_segments]
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Float] the sum of all program segment lengths
|
21
|
-
def length
|
22
|
-
segments.inject(0.0) { |length, segment| length + (segment.last - segment.first) }
|
23
|
-
end
|
24
|
-
|
25
|
-
def == other
|
26
|
-
return other.respond_to?(:segments) && @segments == other.segments
|
27
|
-
end
|
28
|
-
|
29
|
-
def include? offset
|
30
|
-
@segments.each do |segment|
|
31
|
-
if segment.include?(offset)
|
32
|
-
return true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
return false
|
36
|
-
end
|
37
|
-
|
38
|
-
def ensure_increasing_segments
|
39
|
-
non_increasing = @segments.select {|seg| seg.first >= seg.last }
|
40
|
-
if non_increasing.any?
|
41
|
-
raise NonIncreasingError, "Non-increasing segments found #{non_increasing}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def ensure_nonnegative_segments
|
46
|
-
negative = @segments.select {|seg| seg.first < 0 || seg.last < 0 }
|
47
|
-
if negative.any?
|
48
|
-
raise NegativeError, "Segments #{negative} have negative values"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|