mtk 0.0.2 → 0.0.3
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.
- data/.yardopts +3 -2
- data/DEVELOPMENT_NOTES.md +114 -0
- data/INTRO.md +64 -8
- data/LICENSE.txt +1 -1
- data/README.md +31 -102
- data/Rakefile +56 -18
- data/bin/mtk +215 -0
- data/examples/crescendo.rb +5 -5
- data/examples/drum_pattern1.rb +23 -0
- data/examples/dynamic_pattern.rb +8 -11
- data/examples/gets_and_play.rb +26 -0
- data/examples/notation.rb +22 -0
- data/examples/play_midi.rb +8 -10
- data/examples/random_tone_row.rb +2 -2
- data/examples/syntax_to_midi.rb +28 -0
- data/examples/test_output.rb +8 -0
- data/examples/tone_row_melody.rb +6 -6
- data/lib/mtk.rb +52 -40
- data/lib/mtk/chord.rb +55 -0
- data/lib/mtk/constants/durations.rb +57 -0
- data/lib/mtk/constants/intensities.rb +61 -0
- data/lib/mtk/constants/intervals.rb +73 -0
- data/lib/mtk/constants/pitch_classes.rb +29 -0
- data/lib/mtk/constants/pitches.rb +52 -0
- data/lib/mtk/duration.rb +211 -0
- data/lib/mtk/events/event.rb +119 -0
- data/lib/mtk/events/note.rb +112 -0
- data/lib/mtk/events/parameter.rb +54 -0
- data/lib/mtk/helpers/collection.rb +164 -0
- data/lib/mtk/helpers/convert.rb +36 -0
- data/lib/mtk/helpers/lilypond.rb +162 -0
- data/lib/mtk/helpers/output_selector.rb +67 -0
- data/lib/mtk/helpers/pitch_collection.rb +23 -0
- data/lib/mtk/helpers/pseudo_constants.rb +26 -0
- data/lib/mtk/intensity.rb +156 -0
- data/lib/mtk/interval.rb +155 -0
- data/lib/mtk/lang/mtk_grammar.citrus +190 -13
- data/lib/mtk/lang/parser.rb +29 -0
- data/lib/mtk/melody.rb +94 -0
- data/lib/mtk/midi/dls_synth_device.rb +144 -0
- data/lib/mtk/midi/dls_synth_output.rb +62 -0
- data/lib/mtk/midi/file.rb +67 -32
- data/lib/mtk/midi/input.rb +97 -0
- data/lib/mtk/midi/jsound_input.rb +36 -17
- data/lib/mtk/midi/jsound_output.rb +48 -46
- data/lib/mtk/midi/output.rb +195 -0
- data/lib/mtk/midi/unimidi_input.rb +117 -0
- data/lib/mtk/midi/unimidi_output.rb +121 -0
- data/lib/mtk/{_numeric_extensions.rb → numeric_extensions.rb} +12 -0
- data/lib/mtk/patterns/chain.rb +49 -0
- data/lib/mtk/{pattern → patterns}/choice.rb +14 -8
- data/lib/mtk/patterns/cycle.rb +18 -0
- data/lib/mtk/patterns/for_each.rb +71 -0
- data/lib/mtk/patterns/function.rb +39 -0
- data/lib/mtk/{pattern → patterns}/lines.rb +11 -17
- data/lib/mtk/{pattern → patterns}/palindrome.rb +11 -8
- data/lib/mtk/patterns/pattern.rb +171 -0
- data/lib/mtk/patterns/sequence.rb +20 -0
- data/lib/mtk/pitch.rb +7 -6
- data/lib/mtk/pitch_class.rb +124 -46
- data/lib/mtk/pitch_class_set.rb +58 -35
- data/lib/mtk/sequencers/event_builder.rb +131 -0
- data/lib/mtk/sequencers/legato_sequencer.rb +24 -0
- data/lib/mtk/sequencers/rhythmic_sequencer.rb +28 -0
- data/lib/mtk/{sequencer/abstract_sequencer.rb → sequencers/sequencer.rb} +37 -11
- data/lib/mtk/{sequencer → sequencers}/step_sequencer.rb +4 -4
- data/lib/mtk/timeline.rb +39 -22
- data/lib/mtk/variable.rb +32 -0
- data/spec/mtk/chord_spec.rb +83 -0
- data/spec/mtk/{_constants → constants}/durations_spec.rb +12 -41
- data/spec/mtk/{_constants → constants}/intensities_spec.rb +13 -37
- data/spec/mtk/{_constants → constants}/intervals_spec.rb +14 -32
- data/spec/mtk/{_constants → constants}/pitch_classes_spec.rb +8 -4
- data/spec/mtk/{_constants → constants}/pitches_spec.rb +5 -1
- data/spec/mtk/duration_spec.rb +372 -0
- data/spec/mtk/events/event_spec.rb +234 -0
- data/spec/mtk/events/note_spec.rb +174 -0
- data/spec/mtk/events/parameter_spec.rb +220 -0
- data/spec/mtk/{helper → helpers}/collection_spec.rb +86 -3
- data/spec/mtk/{helper → helpers}/pseudo_constants_spec.rb +2 -2
- data/spec/mtk/intensity_spec.rb +289 -0
- data/spec/mtk/interval_spec.rb +265 -0
- data/spec/mtk/lang/parser_spec.rb +597 -0
- data/spec/mtk/melody_spec.rb +223 -0
- data/spec/mtk/midi/file_spec.rb +16 -16
- data/spec/mtk/midi/jsound_input_spec.rb +11 -0
- data/spec/mtk/midi/jsound_output_spec.rb +11 -0
- data/spec/mtk/midi/output_spec.rb +102 -0
- data/spec/mtk/midi/unimidi_input_spec.rb +11 -0
- data/spec/mtk/midi/unimidi_output_spec.rb +11 -0
- data/spec/mtk/{_numeric_extensions_spec.rb → numeric_extensions_spec.rb} +1 -0
- data/spec/mtk/patterns/chain_spec.rb +110 -0
- data/spec/mtk/{pattern → patterns}/choice_spec.rb +20 -30
- data/spec/mtk/{pattern → patterns}/cycle_spec.rb +25 -35
- data/spec/mtk/patterns/for_each_spec.rb +136 -0
- data/spec/mtk/{pattern → patterns}/function_spec.rb +17 -30
- data/spec/mtk/{pattern → patterns}/lines_spec.rb +11 -27
- data/spec/mtk/{pattern → patterns}/palindrome_spec.rb +13 -29
- data/spec/mtk/patterns/pattern_spec.rb +132 -0
- data/spec/mtk/patterns/sequence_spec.rb +203 -0
- data/spec/mtk/pitch_class_set_spec.rb +23 -21
- data/spec/mtk/pitch_class_spec.rb +151 -39
- data/spec/mtk/pitch_spec.rb +22 -1
- data/spec/mtk/sequencers/event_builder_spec.rb +245 -0
- data/spec/mtk/sequencers/legato_sequencer_spec.rb +45 -0
- data/spec/mtk/sequencers/rhythmic_sequencer_spec.rb +84 -0
- data/spec/mtk/sequencers/sequencer_spec.rb +215 -0
- data/spec/mtk/{sequencer → sequencers}/step_sequencer_spec.rb +35 -13
- data/spec/mtk/timeline_spec.rb +109 -16
- data/spec/mtk/variable_spec.rb +52 -0
- data/spec/spec_coverage.rb +2 -0
- data/spec/spec_helper.rb +3 -0
- metadata +188 -91
- data/lib/mtk/_constants/durations.rb +0 -80
- data/lib/mtk/_constants/intensities.rb +0 -81
- data/lib/mtk/_constants/intervals.rb +0 -85
- data/lib/mtk/_constants/pitch_classes.rb +0 -35
- data/lib/mtk/_constants/pitches.rb +0 -49
- data/lib/mtk/event.rb +0 -70
- data/lib/mtk/helper/collection.rb +0 -114
- data/lib/mtk/helper/event_builder.rb +0 -85
- data/lib/mtk/helper/pseudo_constants.rb +0 -26
- data/lib/mtk/lang/grammar.rb +0 -17
- data/lib/mtk/note.rb +0 -63
- data/lib/mtk/pattern/abstract_pattern.rb +0 -132
- data/lib/mtk/pattern/cycle.rb +0 -51
- data/lib/mtk/pattern/enumerator.rb +0 -26
- data/lib/mtk/pattern/function.rb +0 -46
- data/lib/mtk/pattern/sequence.rb +0 -30
- data/lib/mtk/pitch_set.rb +0 -84
- data/lib/mtk/sequencer/rhythmic_sequencer.rb +0 -29
- data/lib/mtk/transform/invertible.rb +0 -15
- data/lib/mtk/transform/mappable.rb +0 -18
- data/lib/mtk/transform/set_theory_operations.rb +0 -34
- data/lib/mtk/transform/transposable.rb +0 -14
- data/spec/mtk/event_spec.rb +0 -139
- data/spec/mtk/helper/event_builder_spec.rb +0 -92
- data/spec/mtk/lang/grammar_spec.rb +0 -100
- data/spec/mtk/note_spec.rb +0 -115
- data/spec/mtk/pattern/abstract_pattern_spec.rb +0 -45
- data/spec/mtk/pattern/note_cycle_spec.rb.bak +0 -116
- data/spec/mtk/pattern/pitch_cycle_spec.rb.bak +0 -47
- data/spec/mtk/pattern/pitch_sequence_spec.rb.bak +0 -37
- data/spec/mtk/pattern/sequence_spec.rb +0 -151
- data/spec/mtk/pitch_set_spec.rb +0 -198
- data/spec/mtk/sequencer/abstract_sequencer_spec.rb +0 -159
- data/spec/mtk/sequencer/rhythmic_sequencer_spec.rb +0 -49
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe MTK::
|
3
|
+
describe MTK::Sequencers::StepSequencer do
|
4
4
|
|
5
|
-
STEP_SEQUENCER =
|
5
|
+
STEP_SEQUENCER = Sequencers::StepSequencer
|
6
6
|
|
7
|
-
let(:pitches) {
|
8
|
-
let(:intensities) {
|
9
|
-
let(:durations) {
|
7
|
+
let(:pitches) { Patterns.PitchSequence(C4, D4, E4) }
|
8
|
+
let(:intensities) { Patterns.IntensitySequence(0.3, 0.7, 1.0) }
|
9
|
+
let(:durations) { Patterns.DurationSequence(1, 1, 2) }
|
10
10
|
let(:step_sequencer) { STEP_SEQUENCER.new [pitches, intensities, durations] }
|
11
11
|
|
12
12
|
describe "#new" do
|
@@ -38,9 +38,17 @@ describe MTK::Sequencer::StepSequencer do
|
|
38
38
|
it "contains notes assembled from the given patterns" do
|
39
39
|
timeline = step_sequencer.to_timeline
|
40
40
|
timeline.should == Timeline.from_hash({
|
41
|
-
0 => Note(C4,0.3
|
42
|
-
1 => Note(D4,0.7
|
43
|
-
2 => Note(E4,1.0
|
41
|
+
0 => Note(C4,1,0.3),
|
42
|
+
1 => Note(D4,1,0.7),
|
43
|
+
2 => Note(E4,2,1.0)
|
44
|
+
})
|
45
|
+
end
|
46
|
+
|
47
|
+
it "treats negative durations as rests" do
|
48
|
+
timeline = STEP_SEQUENCER.new( [pitches, intensities, Patterns.DurationSequence(1, -1, 2)] ).to_timeline
|
49
|
+
timeline.should == Timeline.from_hash({
|
50
|
+
0 => Note(C4,1,0.3),
|
51
|
+
2 => Note(E4,2,1.0)
|
44
52
|
})
|
45
53
|
end
|
46
54
|
end
|
@@ -50,9 +58,9 @@ describe MTK::Sequencer::StepSequencer do
|
|
50
58
|
step_sequencer.step_size = 2
|
51
59
|
timeline = step_sequencer.to_timeline
|
52
60
|
timeline.should == Timeline.from_hash({
|
53
|
-
0 => Note(C4,0.3
|
54
|
-
2 => Note(D4,0.7
|
55
|
-
4 => Note(E4,1.0
|
61
|
+
0 => Note(C4,1,0.3),
|
62
|
+
2 => Note(D4,1,0.7),
|
63
|
+
4 => Note(E4,2,1.0)
|
56
64
|
})
|
57
65
|
end
|
58
66
|
end
|
@@ -62,10 +70,24 @@ describe MTK::Sequencer::StepSequencer do
|
|
62
70
|
step_sequencer.max_steps = 2
|
63
71
|
timeline = step_sequencer.to_timeline
|
64
72
|
timeline.should == Timeline.from_hash({
|
65
|
-
0 => Note(C4,0.3
|
66
|
-
1 => Note(D4,0.7
|
73
|
+
0 => Note(C4,1,0.3),
|
74
|
+
1 => Note(D4,1,0.7)
|
67
75
|
})
|
68
76
|
end
|
69
77
|
end
|
70
78
|
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
describe MTK::Sequencers do
|
83
|
+
|
84
|
+
describe "#StepSequencer" do
|
85
|
+
it "creates a StepSequencer" do
|
86
|
+
MTK::Sequencers.StepSequencer(1,2,3).should be_a MTK::Sequencers::StepSequencer
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets #patterns from the varargs" do
|
90
|
+
MTK::Sequencers.StepSequencer(1,2,3).patterns.should == [1,2,3]
|
91
|
+
end
|
92
|
+
end
|
71
93
|
end
|
data/spec/mtk/timeline_spec.rb
CHANGED
@@ -2,19 +2,19 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe MTK::Timeline do
|
4
4
|
|
5
|
-
let(:note1) { Note
|
6
|
-
let(:note2) { Note
|
7
|
-
let(:timeline_raw_data) { { 0 => note1, 1 => [note1, note2] } }
|
8
|
-
let(:timeline_hash) { { 0 => [note1], 1 => [note1, note2] } }
|
5
|
+
let(:note1) { Note(C4, p, 1) }
|
6
|
+
let(:note2) { Note(G4, o, 2) }
|
7
|
+
let(:timeline_raw_data) { { 0.0 => note1, 1.0 => [note1, note2] } }
|
8
|
+
let(:timeline_hash) { { 0.0 => [note1], 1.0 => [note1, note2] } }
|
9
9
|
let(:timeline) { Timeline.from_hash(timeline_raw_data) }
|
10
10
|
|
11
|
-
let(:unquantized_data) { { 0.0 => [note1], 0.7 => [note1], 1.24 => [note1], 1.25 => [note1] } }
|
11
|
+
let(:unquantized_data) { { 0.0 => [note1], 0.7 => [note1], 1.1 => [note2], 1.24 => [note1], 1.25 => [note1] } }
|
12
12
|
let(:unquantized_timeline) { Timeline.from_hash(unquantized_data) }
|
13
13
|
let(:quantization_interval) { 0.5 }
|
14
|
-
let(:quantized_data) { { 0.0 => [note1], 0.5 => [note1], 1.0 => [note1], 1.5 => [note1] } }
|
14
|
+
let(:quantized_data) { { 0.0 => [note1], 0.5 => [note1], 1.0 => [note2, note1], 1.5 => [note1] } }
|
15
15
|
|
16
|
-
let(:shifted_data) { { 5 => [note1], 6 => [note1, note2] } }
|
17
|
-
let(:reverse_shifted_data) { { -5 => [note1], -4 => [note1, note2] } }
|
16
|
+
let(:shifted_data) { { 5.0 => [note1], 6.0 => [note1, note2] } }
|
17
|
+
let(:reverse_shifted_data) { { -5.0 => [note1], -4.0 => [note1, note2] } }
|
18
18
|
let(:shift_amount) { 5 }
|
19
19
|
|
20
20
|
it "is Enumerable" do
|
@@ -81,24 +81,43 @@ describe MTK::Timeline do
|
|
81
81
|
it "returns nil when no events exist at the timepoint" do
|
82
82
|
timeline[3].should == nil
|
83
83
|
end
|
84
|
+
|
85
|
+
it "coerces the argument for consistent lookup behavior" do
|
86
|
+
timeline[0].should == [note1]
|
87
|
+
timeline[0.0].should == [note1]
|
88
|
+
timeline[Rational(0)].should == [note1]
|
89
|
+
timeline[nil].should == [note1]
|
90
|
+
end
|
84
91
|
end
|
85
92
|
|
93
|
+
|
86
94
|
describe "#[]=" do
|
87
95
|
it "set a single event at the given timepoint" do
|
88
96
|
timeline[5] = note1
|
89
97
|
timeline[5].should == [note1]
|
90
98
|
end
|
99
|
+
|
91
100
|
it "set an array of events at the given timepoint" do
|
92
101
|
timeline[5] = [note1, note2]
|
93
102
|
timeline[5].should == [note1, note2]
|
94
103
|
end
|
104
|
+
|
95
105
|
it "replaces existing events at the timepoint" do
|
96
106
|
timeline[5] = note1
|
97
107
|
timeline[5] = note2
|
98
108
|
timeline[5].should == [note2]
|
99
109
|
end
|
110
|
+
|
111
|
+
it "coerces the argument to floating point for consistent lookup behavior" do
|
112
|
+
timeline = Timeline.new
|
113
|
+
timeline[nil] = note1
|
114
|
+
timeline[1] = note1
|
115
|
+
timeline[Rational(3,2)] = note1
|
116
|
+
timeline.times.should == [0.0, 1.0, 1.5]
|
117
|
+
end
|
100
118
|
end
|
101
119
|
|
120
|
+
|
102
121
|
describe "#add" do
|
103
122
|
it "creates a new event list at a previously empty timepoint" do
|
104
123
|
timeline.add(5, note1)
|
@@ -115,12 +134,25 @@ describe MTK::Timeline do
|
|
115
134
|
timeline.add 5, [note1, note2]
|
116
135
|
timeline[5].should == [note1, note2]
|
117
136
|
end
|
137
|
+
|
138
|
+
it "coerces the argument to floating point for consistent lookup behavior" do
|
139
|
+
timeline = Timeline.new
|
140
|
+
timeline.add(nil, note1)
|
141
|
+
timeline.add(1, note1)
|
142
|
+
timeline.add(Rational(3,2), note1)
|
143
|
+
timeline.times.should == [0.0, 1.0, 1.5]
|
144
|
+
end
|
118
145
|
end
|
119
146
|
|
120
147
|
describe "#delete" do
|
121
148
|
it "removes an event list at the given time" do
|
122
149
|
timeline.delete(1)
|
123
|
-
timeline.should == { 0 => [note1] }
|
150
|
+
timeline.should == { 0.0 => [note1] }
|
151
|
+
end
|
152
|
+
|
153
|
+
it "coerces the argument to floating point for consistent lookup behavior" do
|
154
|
+
timeline.delete(Rational(1))
|
155
|
+
timeline.should == { 0.0 => [note1] }
|
124
156
|
end
|
125
157
|
end
|
126
158
|
|
@@ -139,6 +171,24 @@ describe MTK::Timeline do
|
|
139
171
|
end
|
140
172
|
end
|
141
173
|
|
174
|
+
describe "length" do
|
175
|
+
it "is the lastest time + the longest duration of events at that time" do
|
176
|
+
len = timeline.length
|
177
|
+
len.should be_a ::MTK::Duration
|
178
|
+
len.should == ::MTK.Duration(3)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "empty?" do
|
183
|
+
it "is true when there are no events in the timeline" do
|
184
|
+
Timeline.new.empty?.should be_true
|
185
|
+
end
|
186
|
+
|
187
|
+
it "is false where there are events in the timeline" do
|
188
|
+
timeline.empty?.should be_false
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
142
192
|
describe "#==" do
|
143
193
|
it "is true when the underlying Hashes are equal" do
|
144
194
|
timeline.should == Timeline.from_hash(timeline_hash)
|
@@ -168,7 +218,19 @@ describe MTK::Timeline do
|
|
168
218
|
describe "#map" do
|
169
219
|
it "returns a new Timeline where each [time,event] pair is replaced by the result of block" do
|
170
220
|
mapped = timeline.map{|time,events| [time+1, events.map{|e| e.transpose(time+2) }] }
|
171
|
-
mapped.should == { 1 => [note1.transpose(2)], 2 => [note1.transpose(3), note2.transpose(3)] }
|
221
|
+
mapped.should == { 1.0 => [note1.transpose(2)], 2.0 => [note1.transpose(3), note2.transpose(3)] }
|
222
|
+
end
|
223
|
+
|
224
|
+
it "handle events from different times being mapped to the same time" do
|
225
|
+
timeline = MTK::Timeline.from_hash({ 0.0 => [note1], 1.0 => [note1], 2.0 => [note2] })
|
226
|
+
mapped = timeline.map do |time,events|
|
227
|
+
if events == [note1]
|
228
|
+
[1.0, events]
|
229
|
+
else
|
230
|
+
[2.0, events]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
mapped.should == { 1.0 => [note1,note1], 2.0 => [note2] }
|
172
234
|
end
|
173
235
|
|
174
236
|
it "does not modify this Timeline" do
|
@@ -180,14 +242,14 @@ describe MTK::Timeline do
|
|
180
242
|
describe "#map!" do
|
181
243
|
it "maps the Timeline in place" do
|
182
244
|
timeline.map! {|time,events| [time+1, events.map{|e| e.transpose(time+2) }] }
|
183
|
-
timeline.should == { 1 => [note1.transpose(2)], 2 => [note1.transpose(3), note2.transpose(3)] }
|
245
|
+
timeline.should == { 1.0 => [note1.transpose(2)], 2.0 => [note1.transpose(3), note2.transpose(3)] }
|
184
246
|
end
|
185
247
|
end
|
186
248
|
|
187
249
|
describe "#map_events" do
|
188
250
|
it "maps the Timeline in place" do
|
189
251
|
mapped = timeline.map_events {|event| event.transpose(1) }
|
190
|
-
mapped.should == { 0 => [note1.transpose(1)], 1=> [note1.transpose(1), note2.transpose(1)] }
|
252
|
+
mapped.should == { 0.0 => [note1.transpose(1)], 1.0 => [note1.transpose(1), note2.transpose(1)] }
|
191
253
|
end
|
192
254
|
|
193
255
|
it "does not modify this Timeline" do
|
@@ -198,8 +260,8 @@ describe MTK::Timeline do
|
|
198
260
|
|
199
261
|
describe "#map_events!" do
|
200
262
|
it "maps the Timeline in place" do
|
201
|
-
timeline.map_events! {|event| event.transpose(1) }
|
202
|
-
timeline.should == { 0 => [note1.transpose(1)], 1=> [note1.transpose(1), note2.transpose(1)] }
|
263
|
+
timeline.map_events! {|event| event.transpose(1.0) }
|
264
|
+
timeline.should == { 0.0 => [note1.transpose(1)], 1.0 => [note1.transpose(1), note2.transpose(1)] }
|
203
265
|
end
|
204
266
|
end
|
205
267
|
|
@@ -294,13 +356,18 @@ describe MTK::Timeline do
|
|
294
356
|
describe "#flatten" do
|
295
357
|
it "flattens nested timelines so that all nested subtimes are converted to absolute times in a single timeline" do
|
296
358
|
timeline[10] = Timeline.from_hash({ 0 => note2, 1 => note1 })
|
297
|
-
timeline.flatten.should == timeline_hash.merge({ 10 => [note2], 11 => [note1] })
|
359
|
+
timeline.flatten.should == timeline_hash.merge({ 10.0 => [note2], 11.0 => [note1] })
|
298
360
|
end
|
299
361
|
|
300
362
|
it "handles nested timelines which have nested timelines inside of them" do
|
301
363
|
nested = Timeline.from_hash({ 0 => note1 })
|
302
364
|
timeline[10] = Timeline.from_hash({ 100 => nested })
|
303
|
-
timeline.flatten.should == timeline_hash.merge({ 110 => [note1] })
|
365
|
+
timeline.flatten.should == timeline_hash.merge({ 110.0 => [note1] })
|
366
|
+
end
|
367
|
+
|
368
|
+
it "handles multiple nested timeslines at the same time point" do
|
369
|
+
timeline[10] = [Timeline.from_hash({ 0 => note2, 1 => note1 }), Timeline.from_hash({ 2 => note1, 3 => note2 })]
|
370
|
+
timeline.flatten.should == timeline_hash.merge({ 10.0 => [note2], 11.0 => [note1], 12.0 => [note1], 13.0 => [note2] })
|
304
371
|
end
|
305
372
|
|
306
373
|
it "returns a new Timeline" do
|
@@ -333,5 +400,31 @@ describe MTK::Timeline do
|
|
333
400
|
Timeline.quantize_time(13,2.5).should == 12.5
|
334
401
|
end
|
335
402
|
end
|
403
|
+
|
404
|
+
describe "#to_s" do
|
405
|
+
it "has one line per time" do
|
406
|
+
timeline.to_s.split("\n").size.should == timeline.times.size
|
407
|
+
end
|
408
|
+
|
409
|
+
it "has a time => event_list mapping on each line" do
|
410
|
+
for line in timeline.to_s.split("\n")
|
411
|
+
line.should =~ /=>/
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
it "pretty prints the output by aligning all '=>' arrows" do
|
416
|
+
# alignment is only a factor when the times have different numbers of digits:
|
417
|
+
timeline = Timeline.new
|
418
|
+
timeline.add 0, note1
|
419
|
+
timeline.add 10, note1
|
420
|
+
timeline.add 1000, note1
|
421
|
+
lines = timeline.to_s.split("\n")
|
422
|
+
last = lines.pop
|
423
|
+
arrow_position = last =~ /=>/
|
424
|
+
for line in lines
|
425
|
+
(line =~ /=>/).should == arrow_position
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
336
429
|
end
|
337
430
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MTK::Variable do
|
4
|
+
|
5
|
+
def var(*args)
|
6
|
+
::MTK::Variable.new(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#name' do
|
10
|
+
it 'is the name the variable was constructed with' do
|
11
|
+
var('$').name.should == '$'
|
12
|
+
var('$$').name.should == '$$'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'cannot be changed after the variable is created' do
|
16
|
+
lambda{ var('$').name = '$$$' }.should raise_error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#value' do
|
21
|
+
it 'is the value the variable was constructed with' do
|
22
|
+
var(:name, :value).value.should == :value
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can be changed after the variable is created' do
|
26
|
+
v = var(:name, :value)
|
27
|
+
v.value = 'foo'
|
28
|
+
v.value.should == 'foo'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#==' do
|
33
|
+
it "is true when two variables' names are equal" do
|
34
|
+
var('$').should == var('$')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "is false when two variables' names are not equal" do
|
38
|
+
var('$').should_not == var('$$')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#to_s' do
|
43
|
+
it "includes just the variable name when there's no value" do
|
44
|
+
var('$').to_s.should == 'MTK::Variable<$>'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "includes just the variable name and value when there's a value" do
|
48
|
+
var('x',1).to_s.should == 'MTK::Variable<x=1>'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,134 +1,231 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: mtk
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.2
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Adam Murray
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: citrus
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.4'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.4'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: midilib
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: gamelan
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.3'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.3'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: unimidi
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.3'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.3'
|
78
|
+
description: A music library and domain-specific language for generating music via
|
79
|
+
MIDI.
|
17
80
|
email: adam@compusition.com
|
18
|
-
executables:
|
19
|
-
|
81
|
+
executables:
|
82
|
+
- mtk
|
20
83
|
extensions: []
|
21
|
-
|
22
84
|
extra_rdoc_files: []
|
23
|
-
|
24
|
-
files:
|
85
|
+
files:
|
25
86
|
- Rakefile
|
87
|
+
- DEVELOPMENT_NOTES.md
|
26
88
|
- INTRO.md
|
27
89
|
- README.md
|
28
90
|
- LICENSE.txt
|
29
91
|
- .yardopts
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
33
|
-
-
|
34
|
-
-
|
35
|
-
-
|
36
|
-
-
|
37
|
-
-
|
38
|
-
-
|
39
|
-
-
|
40
|
-
-
|
92
|
+
- bin/mtk
|
93
|
+
- examples/crescendo.rb
|
94
|
+
- examples/drum_pattern1.rb
|
95
|
+
- examples/dynamic_pattern.rb
|
96
|
+
- examples/gets_and_play.rb
|
97
|
+
- examples/notation.rb
|
98
|
+
- examples/play_midi.rb
|
99
|
+
- examples/print_midi.rb
|
100
|
+
- examples/random_tone_row.rb
|
101
|
+
- examples/syntax_to_midi.rb
|
102
|
+
- examples/test_output.rb
|
103
|
+
- examples/tone_row_melody.rb
|
104
|
+
- lib/mtk/chord.rb
|
105
|
+
- lib/mtk/constants/durations.rb
|
106
|
+
- lib/mtk/constants/intensities.rb
|
107
|
+
- lib/mtk/constants/intervals.rb
|
108
|
+
- lib/mtk/constants/pitch_classes.rb
|
109
|
+
- lib/mtk/constants/pitches.rb
|
110
|
+
- lib/mtk/duration.rb
|
111
|
+
- lib/mtk/events/event.rb
|
112
|
+
- lib/mtk/events/note.rb
|
113
|
+
- lib/mtk/events/parameter.rb
|
114
|
+
- lib/mtk/helpers/collection.rb
|
115
|
+
- lib/mtk/helpers/convert.rb
|
116
|
+
- lib/mtk/helpers/lilypond.rb
|
117
|
+
- lib/mtk/helpers/output_selector.rb
|
118
|
+
- lib/mtk/helpers/pitch_collection.rb
|
119
|
+
- lib/mtk/helpers/pseudo_constants.rb
|
120
|
+
- lib/mtk/intensity.rb
|
121
|
+
- lib/mtk/interval.rb
|
41
122
|
- lib/mtk/lang/mtk_grammar.citrus
|
123
|
+
- lib/mtk/lang/parser.rb
|
124
|
+
- lib/mtk/melody.rb
|
125
|
+
- lib/mtk/midi/dls_synth_device.rb
|
126
|
+
- lib/mtk/midi/dls_synth_output.rb
|
42
127
|
- lib/mtk/midi/file.rb
|
128
|
+
- lib/mtk/midi/input.rb
|
43
129
|
- lib/mtk/midi/jsound_input.rb
|
44
130
|
- lib/mtk/midi/jsound_output.rb
|
45
|
-
- lib/mtk/
|
46
|
-
- lib/mtk/
|
47
|
-
- lib/mtk/
|
48
|
-
- lib/mtk/
|
49
|
-
- lib/mtk/
|
50
|
-
- lib/mtk/
|
51
|
-
- lib/mtk/
|
52
|
-
- lib/mtk/
|
53
|
-
- lib/mtk/
|
131
|
+
- lib/mtk/midi/output.rb
|
132
|
+
- lib/mtk/midi/unimidi_input.rb
|
133
|
+
- lib/mtk/midi/unimidi_output.rb
|
134
|
+
- lib/mtk/numeric_extensions.rb
|
135
|
+
- lib/mtk/patterns/chain.rb
|
136
|
+
- lib/mtk/patterns/choice.rb
|
137
|
+
- lib/mtk/patterns/cycle.rb
|
138
|
+
- lib/mtk/patterns/for_each.rb
|
139
|
+
- lib/mtk/patterns/function.rb
|
140
|
+
- lib/mtk/patterns/lines.rb
|
141
|
+
- lib/mtk/patterns/palindrome.rb
|
142
|
+
- lib/mtk/patterns/pattern.rb
|
143
|
+
- lib/mtk/patterns/sequence.rb
|
54
144
|
- lib/mtk/pitch.rb
|
55
145
|
- lib/mtk/pitch_class.rb
|
56
146
|
- lib/mtk/pitch_class_set.rb
|
57
|
-
- lib/mtk/
|
58
|
-
- lib/mtk/
|
59
|
-
- lib/mtk/
|
60
|
-
- lib/mtk/sequencer
|
147
|
+
- lib/mtk/sequencers/event_builder.rb
|
148
|
+
- lib/mtk/sequencers/legato_sequencer.rb
|
149
|
+
- lib/mtk/sequencers/rhythmic_sequencer.rb
|
150
|
+
- lib/mtk/sequencers/sequencer.rb
|
151
|
+
- lib/mtk/sequencers/step_sequencer.rb
|
61
152
|
- lib/mtk/timeline.rb
|
62
|
-
- lib/mtk/
|
63
|
-
- lib/mtk/transform/mappable.rb
|
64
|
-
- lib/mtk/transform/set_theory_operations.rb
|
65
|
-
- lib/mtk/transform/transposable.rb
|
153
|
+
- lib/mtk/variable.rb
|
66
154
|
- lib/mtk.rb
|
67
|
-
- spec/mtk/
|
68
|
-
- spec/mtk/
|
69
|
-
- spec/mtk/
|
70
|
-
- spec/mtk/
|
71
|
-
- spec/mtk/
|
72
|
-
- spec/mtk/
|
73
|
-
- spec/mtk/
|
74
|
-
- spec/mtk/
|
75
|
-
- spec/mtk/
|
76
|
-
- spec/mtk/
|
77
|
-
- spec/mtk/
|
155
|
+
- spec/mtk/chord_spec.rb
|
156
|
+
- spec/mtk/constants/durations_spec.rb
|
157
|
+
- spec/mtk/constants/intensities_spec.rb
|
158
|
+
- spec/mtk/constants/intervals_spec.rb
|
159
|
+
- spec/mtk/constants/pitch_classes_spec.rb
|
160
|
+
- spec/mtk/constants/pitches_spec.rb
|
161
|
+
- spec/mtk/duration_spec.rb
|
162
|
+
- spec/mtk/events/event_spec.rb
|
163
|
+
- spec/mtk/events/note_spec.rb
|
164
|
+
- spec/mtk/events/parameter_spec.rb
|
165
|
+
- spec/mtk/helpers/collection_spec.rb
|
166
|
+
- spec/mtk/helpers/pseudo_constants_spec.rb
|
167
|
+
- spec/mtk/intensity_spec.rb
|
168
|
+
- spec/mtk/interval_spec.rb
|
169
|
+
- spec/mtk/lang/parser_spec.rb
|
170
|
+
- spec/mtk/melody_spec.rb
|
78
171
|
- spec/mtk/midi/file_spec.rb
|
79
|
-
- spec/mtk/
|
80
|
-
- spec/mtk/
|
81
|
-
- spec/mtk/
|
82
|
-
- spec/mtk/
|
83
|
-
- spec/mtk/
|
84
|
-
- spec/mtk/
|
85
|
-
- spec/mtk/
|
86
|
-
- spec/mtk/
|
87
|
-
- spec/mtk/
|
88
|
-
- spec/mtk/
|
89
|
-
- spec/mtk/
|
172
|
+
- spec/mtk/midi/jsound_input_spec.rb
|
173
|
+
- spec/mtk/midi/jsound_output_spec.rb
|
174
|
+
- spec/mtk/midi/output_spec.rb
|
175
|
+
- spec/mtk/midi/unimidi_input_spec.rb
|
176
|
+
- spec/mtk/midi/unimidi_output_spec.rb
|
177
|
+
- spec/mtk/numeric_extensions_spec.rb
|
178
|
+
- spec/mtk/patterns/chain_spec.rb
|
179
|
+
- spec/mtk/patterns/choice_spec.rb
|
180
|
+
- spec/mtk/patterns/cycle_spec.rb
|
181
|
+
- spec/mtk/patterns/for_each_spec.rb
|
182
|
+
- spec/mtk/patterns/function_spec.rb
|
183
|
+
- spec/mtk/patterns/lines_spec.rb
|
184
|
+
- spec/mtk/patterns/palindrome_spec.rb
|
185
|
+
- spec/mtk/patterns/pattern_spec.rb
|
186
|
+
- spec/mtk/patterns/sequence_spec.rb
|
90
187
|
- spec/mtk/pitch_class_set_spec.rb
|
91
188
|
- spec/mtk/pitch_class_spec.rb
|
92
|
-
- spec/mtk/pitch_set_spec.rb
|
93
189
|
- spec/mtk/pitch_spec.rb
|
94
|
-
- spec/mtk/
|
95
|
-
- spec/mtk/
|
96
|
-
- spec/mtk/
|
190
|
+
- spec/mtk/sequencers/event_builder_spec.rb
|
191
|
+
- spec/mtk/sequencers/legato_sequencer_spec.rb
|
192
|
+
- spec/mtk/sequencers/rhythmic_sequencer_spec.rb
|
193
|
+
- spec/mtk/sequencers/sequencer_spec.rb
|
194
|
+
- spec/mtk/sequencers/step_sequencer_spec.rb
|
97
195
|
- spec/mtk/timeline_spec.rb
|
196
|
+
- spec/mtk/variable_spec.rb
|
197
|
+
- spec/spec_coverage.rb
|
98
198
|
- spec/spec_helper.rb
|
99
199
|
- spec/test.mid
|
100
|
-
- examples/crescendo.rb
|
101
|
-
- examples/dynamic_pattern.rb
|
102
|
-
- examples/play_midi.rb
|
103
|
-
- examples/print_midi.rb
|
104
|
-
- examples/random_tone_row.rb
|
105
|
-
- examples/tone_row_melody.rb
|
106
200
|
homepage: http://github.com/adamjmurray/mtk
|
107
201
|
licenses: []
|
108
|
-
|
109
202
|
post_install_message:
|
110
203
|
rdoc_options: []
|
111
|
-
|
112
|
-
require_paths:
|
204
|
+
require_paths:
|
113
205
|
- lib
|
114
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
207
|
none: false
|
116
|
-
requirements:
|
117
|
-
- -
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
version:
|
120
|
-
|
208
|
+
requirements:
|
209
|
+
- - ! '>='
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '0'
|
212
|
+
segments:
|
213
|
+
- 0
|
214
|
+
hash: 1581692375724578374
|
215
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
216
|
none: false
|
122
|
-
requirements:
|
123
|
-
- -
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version:
|
217
|
+
requirements:
|
218
|
+
- - ! '>='
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '0'
|
221
|
+
segments:
|
222
|
+
- 0
|
223
|
+
hash: 1581692375724578374
|
126
224
|
requirements: []
|
127
|
-
|
128
225
|
rubyforge_project:
|
129
|
-
rubygems_version: 1.8.
|
226
|
+
rubygems_version: 1.8.25
|
130
227
|
signing_key:
|
131
228
|
specification_version: 3
|
132
|
-
summary: Music
|
229
|
+
summary: Music Tool Kit for Ruby
|
133
230
|
test_files: []
|
134
|
-
|
231
|
+
has_rdoc:
|