jmtk 0.0.3.3-java → 0.4-java
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 +15 -0
- data/DEVELOPMENT_NOTES.md +20 -0
- data/INTRO.md +63 -31
- data/README.md +9 -3
- data/Rakefile +42 -42
- data/bin/jmtk +75 -32
- data/bin/mtk +75 -32
- data/examples/drum_pattern.rb +2 -2
- data/examples/dynamic_pattern.rb +1 -1
- data/examples/helpers/output_selector.rb +71 -0
- data/examples/notation.rb +5 -1
- data/examples/tone_row_melody.rb +1 -1
- data/lib/mtk.rb +1 -0
- data/lib/mtk/core/duration.rb +18 -3
- data/lib/mtk/core/intensity.rb +5 -3
- data/lib/mtk/core/interval.rb +21 -14
- data/lib/mtk/core/pitch.rb +2 -0
- data/lib/mtk/core/pitch_class.rb +6 -3
- data/lib/mtk/events/event.rb +2 -1
- data/lib/mtk/events/note.rb +1 -1
- data/lib/mtk/events/parameter.rb +1 -0
- data/lib/mtk/events/rest.rb +85 -0
- data/lib/mtk/events/timeline.rb +6 -2
- data/lib/mtk/io/jsound_input.rb +9 -3
- data/lib/mtk/io/midi_file.rb +38 -2
- data/lib/mtk/io/midi_input.rb +1 -1
- data/lib/mtk/io/midi_output.rb +95 -4
- data/lib/mtk/io/unimidi_input.rb +7 -3
- data/lib/mtk/lang/durations.rb +31 -26
- data/lib/mtk/lang/intensities.rb +29 -30
- data/lib/mtk/lang/intervals.rb +108 -41
- data/lib/mtk/lang/mtk_grammar.citrus +14 -4
- data/lib/mtk/lang/parser.rb +10 -5
- data/lib/mtk/lang/pitch_classes.rb +45 -17
- data/lib/mtk/lang/pitches.rb +169 -32
- data/lib/mtk/lang/tutorial.rb +279 -0
- data/lib/mtk/lang/tutorial_lesson.rb +87 -0
- data/lib/mtk/sequencers/event_builder.rb +29 -8
- data/spec/mtk/core/duration_spec.rb +14 -1
- data/spec/mtk/core/intensity_spec.rb +1 -1
- data/spec/mtk/events/event_spec.rb +10 -16
- data/spec/mtk/events/note_spec.rb +3 -3
- data/spec/mtk/events/rest_spec.rb +184 -0
- data/spec/mtk/events/timeline_spec.rb +5 -1
- data/spec/mtk/io/midi_file_spec.rb +13 -2
- data/spec/mtk/io/midi_output_spec.rb +42 -9
- data/spec/mtk/lang/durations_spec.rb +5 -5
- data/spec/mtk/lang/intensities_spec.rb +5 -5
- data/spec/mtk/lang/intervals_spec.rb +139 -13
- data/spec/mtk/lang/parser_spec.rb +65 -25
- data/spec/mtk/lang/pitch_classes_spec.rb +0 -11
- data/spec/mtk/lang/pitches_spec.rb +0 -15
- data/spec/mtk/patterns/chain_spec.rb +7 -7
- data/spec/mtk/patterns/for_each_spec.rb +2 -2
- data/spec/mtk/sequencers/event_builder_spec.rb +49 -17
- metadata +12 -22
@@ -48,15 +48,4 @@ describe MTK::Lang::PitchClasses do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
describe ".[]" do
|
52
|
-
it "acts like PitchClass.[]" do
|
53
|
-
for name in PitchClasses::PITCH_CLASS_NAMES
|
54
|
-
PitchClasses[name].should == PitchClass[name]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
it "returns nil for arguments it doesn't understand" do
|
59
|
-
PitchClasses[:invalid].should be_nil
|
60
|
-
end
|
61
|
-
end
|
62
51
|
end
|
@@ -38,19 +38,4 @@ describe MTK::Lang::Pitches do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
describe ".[]" do
|
42
|
-
it "acts like Pitch.from_s for the names in PITCH_NAMES, and also treats '_' like '-'" do
|
43
|
-
for name in Pitches::PITCH_NAMES
|
44
|
-
Pitches[name].should == Pitch.from_s(name.sub('_','-')) # the constant names need to use underscores, but Pitch.from_s doesn't understand that
|
45
|
-
if name =~ /_/
|
46
|
-
Pitches[name.sub('_','-')].should == Pitch.from_s(name.sub('_','-')) # make sure '-' works too
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it "returns nil for arguments it doesn't understand" do
|
52
|
-
Pitches[:invalid].should be_nil
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
41
|
end
|
@@ -43,11 +43,11 @@ describe MTK::Patterns::Chain do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'combines 2 patterns, and returns #next until the last StopIteration of a nested Pattern occurs' do
|
46
|
-
chain = CHAIN.new [Patterns.Sequence(C,D,E), Patterns.Sequence(w,h,q,
|
46
|
+
chain = CHAIN.new [Patterns.Sequence(C,D,E), Patterns.Sequence(w,h,q,e)]
|
47
47
|
chain.next.should == [C,w]
|
48
48
|
chain.next.should == [D,h]
|
49
49
|
chain.next.should == [E,q]
|
50
|
-
chain.next.should == [C,
|
50
|
+
chain.next.should == [C,e]
|
51
51
|
lambda{ chain.next }.should raise_error StopIteration
|
52
52
|
end
|
53
53
|
|
@@ -56,18 +56,18 @@ describe MTK::Patterns::Chain do
|
|
56
56
|
|
57
57
|
|
58
58
|
it 'combines Choice patterns with max_cycles' do
|
59
|
-
chain = CHAIN.new [Patterns.Choice(
|
59
|
+
chain = CHAIN.new [Patterns.Choice(e,s), Patterns.Choice(C,D,E)], max_cycles:100
|
60
60
|
100.times do |time|
|
61
61
|
attrs = chain.next
|
62
62
|
attrs.length.should == 2
|
63
|
-
(attrs[0]==
|
63
|
+
(attrs[0]==e or attrs[0]==s).should be_true
|
64
64
|
(attrs[1]==C or attrs[1]==D or attrs[1]==E).should be_true
|
65
65
|
end
|
66
66
|
lambda{ chain.next }.should raise_error StopIteration
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'combines Choice patterns and emits a only single combination of attributes by default' do
|
70
|
-
chain = CHAIN.new [Patterns.Choice(
|
70
|
+
chain = CHAIN.new [Patterns.Choice(e,s), Patterns.Choice(C,D,E)]
|
71
71
|
chain.next
|
72
72
|
lambda{ chain.next }.should raise_error StopIteration
|
73
73
|
end
|
@@ -78,7 +78,7 @@ describe MTK::Patterns::Chain do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'throws StopIteration when any subpattern throws StopIteration with max_elements_exceeded' do
|
81
|
-
chain = CHAIN.new [Patterns.Sequence(C,D,E,F,G), Patterns.Sequence(w,h,q,
|
81
|
+
chain = CHAIN.new [Patterns.Sequence(C,D,E,F,G), Patterns.Sequence(w,h,q,e, max_elements:3)]
|
82
82
|
chain.next.should == [C,w]
|
83
83
|
chain.next.should == [D,h]
|
84
84
|
chain.next.should == [E,q]
|
@@ -100,7 +100,7 @@ describe MTK::Patterns::Chain do
|
|
100
100
|
chain = CHAIN.new [C,q]
|
101
101
|
chain.next
|
102
102
|
chain.rewind
|
103
|
-
lambda{ chain.next }.should_not raise_error
|
103
|
+
lambda{ chain.next }.should_not raise_error
|
104
104
|
lambda{ chain.next }.should raise_error StopIteration
|
105
105
|
end
|
106
106
|
end
|
@@ -83,11 +83,11 @@ describe MTK::Patterns::ForEach do
|
|
83
83
|
|
84
84
|
it "evaluates nested variables" do
|
85
85
|
# (C4 Bb Ab G)@( (C D C $):(q i i)*4:(mp mf) )
|
86
|
-
foreach = FOREACH.new( [seq(G,A), chain(seq(C,D,var('$')),seq(q,
|
86
|
+
foreach = FOREACH.new( [seq(G,A), chain(seq(C,D,var('$')),seq(q,e,s))] )
|
87
87
|
vals = []
|
88
88
|
6.times{ vals << foreach.next }
|
89
89
|
lambda{ foreach.next }.should raise_error StopIteration
|
90
|
-
vals.should == [[C,q],[D,
|
90
|
+
vals.should == [[C,q],[D,e],[G,s],[C,q],[D,e],[A,s]]
|
91
91
|
end
|
92
92
|
|
93
93
|
end
|
@@ -57,20 +57,26 @@ describe MTK::Sequencers::EventBuilder do
|
|
57
57
|
event_builder.next.should == notes(C4)
|
58
58
|
end
|
59
59
|
|
60
|
-
it "defaults to intensity '
|
60
|
+
it "defaults to intensity 'f' when no intensities are given" do
|
61
61
|
event_builder = EVENT_BUILDER.new [Patterns.PitchSequence(C4, D4, E4), Patterns.DurationCycle(2)]
|
62
|
-
event_builder.next.should == [Note(C4,
|
63
|
-
event_builder.next.should == [Note(D4,
|
64
|
-
event_builder.next.should == [Note(E4,
|
62
|
+
event_builder.next.should == [Note(C4, f, 2)]
|
63
|
+
event_builder.next.should == [Note(D4, f, 2)]
|
64
|
+
event_builder.next.should == [Note(E4, f, 2)]
|
65
65
|
end
|
66
66
|
|
67
67
|
it "defaults to duration 1 when no durations are given" do
|
68
|
-
event_builder = EVENT_BUILDER.new [Patterns.PitchSequence(C4, D4, E4), Patterns.IntensityCycle(p,
|
68
|
+
event_builder = EVENT_BUILDER.new [Patterns.PitchSequence(C4, D4, E4), Patterns.IntensityCycle(p,f)]
|
69
69
|
event_builder.next.should == [Note(C4, p, 1)]
|
70
|
-
event_builder.next.should == [Note(D4,
|
70
|
+
event_builder.next.should == [Note(D4, f, 1)]
|
71
71
|
event_builder.next.should == [Note(E4, p, 1)]
|
72
72
|
end
|
73
73
|
|
74
|
+
it "builds notes from pitch class sets, selecting the first pitches nearest to the default pitch" do
|
75
|
+
pitch_class_sequence = MTK::Patterns::Sequence.new([PitchClassSet(C,G)])
|
76
|
+
event_builder = EVENT_BUILDER.new [pitch_class_sequence], :default_pitch => D3
|
77
|
+
event_builder.next.should == notes(C3,G3)
|
78
|
+
end
|
79
|
+
|
74
80
|
it "builds notes from pitch class sets, selecting the nearest pitch classes to the previous/default pitch" do
|
75
81
|
pitch_class_sequence = MTK::Patterns::Sequence.new([PitchClassSet(C,G),PitchClassSet(B,Eb),PitchClassSet(D,C)])
|
76
82
|
event_builder = EVENT_BUILDER.new [pitch_class_sequence], :default_pitch => D3
|
@@ -108,17 +114,17 @@ describe MTK::Sequencers::EventBuilder do
|
|
108
114
|
end
|
109
115
|
|
110
116
|
it "iterates through the pitch, intensity, and duration list in parallel to emit Notes" do
|
111
|
-
event_builder = EVENT_BUILDER.new [Patterns.PitchCycle(C4, D4, E4), Patterns.IntensityCycle(p,
|
117
|
+
event_builder = EVENT_BUILDER.new [Patterns.PitchCycle(C4, D4, E4), Patterns.IntensityCycle(p, f), Patterns.DurationCycle(1,2,3,4)]
|
112
118
|
event_builder.next.should == [Note(C4, p, 1)]
|
113
|
-
event_builder.next.should == [Note(D4,
|
119
|
+
event_builder.next.should == [Note(D4, f, 2)]
|
114
120
|
event_builder.next.should == [Note(E4, p, 3)]
|
115
|
-
event_builder.next.should == [Note(C4,
|
121
|
+
event_builder.next.should == [Note(C4, f, 4)]
|
116
122
|
event_builder.next.should == [Note(D4, p, 1)]
|
117
|
-
event_builder.next.should == [Note(E4,
|
123
|
+
event_builder.next.should == [Note(E4, f, 2)]
|
118
124
|
end
|
119
125
|
|
120
126
|
it "returns nil (for a rest) when it encounters a nil value" do
|
121
|
-
event_builder = EVENT_BUILDER.new [Patterns.PitchCycle(C4, D4, E4, F4, nil), Patterns.IntensityCycle(mp, mf,
|
127
|
+
event_builder = EVENT_BUILDER.new [Patterns.PitchCycle(C4, D4, E4, F4, nil), Patterns.IntensityCycle(mp, mf, f, nil), Patterns.DurationCycle(1, 2, nil)]
|
122
128
|
event_builder.next.should == [Note(C4, mp, 1)]
|
123
129
|
event_builder.next.should == [Note(D4, mf, 2)]
|
124
130
|
event_builder.next.should be_nil
|
@@ -166,10 +172,10 @@ describe MTK::Sequencers::EventBuilder do
|
|
166
172
|
end
|
167
173
|
|
168
174
|
it "uses the default_pitch when no pitch pattern is provided" do
|
169
|
-
event_builder = EVENT_BUILDER.new [Patterns.Cycle( mp, mf,
|
175
|
+
event_builder = EVENT_BUILDER.new [Patterns.Cycle( mp, mf, f )], :default_pitch => G3
|
170
176
|
event_builder.next.should == [Note(G3,mp,1)]
|
171
177
|
event_builder.next.should == [Note(G3,mf,1)]
|
172
|
-
event_builder.next.should == [Note(G3,
|
178
|
+
event_builder.next.should == [Note(G3,f,1)]
|
173
179
|
end
|
174
180
|
|
175
181
|
it "handles chains of sequences" do
|
@@ -204,8 +210,8 @@ describe MTK::Sequencers::EventBuilder do
|
|
204
210
|
end
|
205
211
|
|
206
212
|
it "adds chained durations together" do
|
207
|
-
event_builder = EVENT_BUILDER.new( [Patterns.Chain(h,q,
|
208
|
-
event_builder.next[0].duration.should == h+q+
|
213
|
+
event_builder = EVENT_BUILDER.new( [Patterns.Chain(h,q,e,s)] )
|
214
|
+
event_builder.next[0].duration.should == h+q+e+s
|
209
215
|
end
|
210
216
|
|
211
217
|
it "averages chained intensities together" do
|
@@ -215,11 +221,11 @@ describe MTK::Sequencers::EventBuilder do
|
|
215
221
|
|
216
222
|
it "defaults the intensity to the previous intensity" do
|
217
223
|
event_builder = EVENT_BUILDER.new(
|
218
|
-
[Patterns.Sequence(Patterns.Chain(C4,ppp,q), Patterns.Chain(D4,
|
224
|
+
[Patterns.Sequence(Patterns.Chain(C4,ppp,q), Patterns.Chain(D4,e), Patterns.Chain(E4,ff,h), Patterns.Chain(F4,e))]
|
219
225
|
)
|
220
226
|
notes = []
|
221
227
|
4.times{ notes += event_builder.next }
|
222
|
-
notes.should == [Note(C4,ppp,q), Note(D4,ppp,
|
228
|
+
notes.should == [Note(C4,ppp,q), Note(D4,ppp,e), Note(E4,ff,h), Note(F4,ff,e)]
|
223
229
|
end
|
224
230
|
|
225
231
|
it "defaults the duration to the previous duration" do
|
@@ -230,6 +236,32 @@ describe MTK::Sequencers::EventBuilder do
|
|
230
236
|
4.times{ notes += event_builder.next }
|
231
237
|
notes.should == [Note(C4,ppp,h), Note(D4,mp,h), Note(E4,ff,s), Note(F4,mf,s)]
|
232
238
|
end
|
239
|
+
|
240
|
+
it "uses the previous pitch class in the chain to determine the octave of the current pitch class" do
|
241
|
+
event_builder = EVENT_BUILDER.new([Patterns.Chain(C4,E,G)])
|
242
|
+
event_builder.next.should == [Note(C4),Note(E4),Note(G4)]
|
243
|
+
end
|
244
|
+
|
245
|
+
it "returns a Rest event when the duration is negative" do
|
246
|
+
event_builder = EVENT_BUILDER.new([Patterns.Chain(C4,-q)])
|
247
|
+
event_builder.next.should == [Rest(q)]
|
248
|
+
end
|
249
|
+
|
250
|
+
it "doesn't uses the absolute value of the previous rest when generating the next event" do
|
251
|
+
event_builder = EVENT_BUILDER.new([Patterns.Sequence(Patterns.Chain(C4,q), -q, D4)])
|
252
|
+
event_builder.next.should == [Note(C4,q)]
|
253
|
+
event_builder.next.should == [Rest(q)]
|
254
|
+
event_builder.next.should == [Note(D4,q)]
|
255
|
+
end
|
256
|
+
|
257
|
+
it "makes all event chained to a rest be a rest" do
|
258
|
+
event_builder = EVENT_BUILDER.new(
|
259
|
+
[Patterns.Sequence(Patterns.Chain(C4,q), Patterns.Chain(-q, Patterns.Sequence(D4,E4)))]
|
260
|
+
)
|
261
|
+
event_builder.next.should == [Note(C4,q)]
|
262
|
+
event_builder.next.should == [Rest(q)]
|
263
|
+
event_builder.next.should == [Rest(q)]
|
264
|
+
end
|
233
265
|
end
|
234
266
|
|
235
267
|
describe "#rewind" do
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jmtk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: '0.4'
|
6
5
|
platform: java
|
7
6
|
authors:
|
8
7
|
- Adam Murray
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: citrus
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: midilib
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: gamelan
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: jsound
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -95,6 +86,7 @@ files:
|
|
95
86
|
- examples/drum_pattern.rb
|
96
87
|
- examples/dynamic_pattern.rb
|
97
88
|
- examples/gets_and_play.rb
|
89
|
+
- examples/helpers/output_selector.rb
|
98
90
|
- examples/notation.rb
|
99
91
|
- examples/play_midi.rb
|
100
92
|
- examples/print_midi.rb
|
@@ -110,6 +102,7 @@ files:
|
|
110
102
|
- lib/mtk/events/event.rb
|
111
103
|
- lib/mtk/events/note.rb
|
112
104
|
- lib/mtk/events/parameter.rb
|
105
|
+
- lib/mtk/events/rest.rb
|
113
106
|
- lib/mtk/events/timeline.rb
|
114
107
|
- lib/mtk/groups/chord.rb
|
115
108
|
- lib/mtk/groups/collection.rb
|
@@ -134,6 +127,8 @@ files:
|
|
134
127
|
- lib/mtk/lang/pitch_classes.rb
|
135
128
|
- lib/mtk/lang/pitches.rb
|
136
129
|
- lib/mtk/lang/pseudo_constants.rb
|
130
|
+
- lib/mtk/lang/tutorial.rb
|
131
|
+
- lib/mtk/lang/tutorial_lesson.rb
|
137
132
|
- lib/mtk/lang/variable.rb
|
138
133
|
- lib/mtk/numeric_extensions.rb
|
139
134
|
- lib/mtk/patterns/chain.rb
|
@@ -159,6 +154,7 @@ files:
|
|
159
154
|
- spec/mtk/events/event_spec.rb
|
160
155
|
- spec/mtk/events/note_spec.rb
|
161
156
|
- spec/mtk/events/parameter_spec.rb
|
157
|
+
- spec/mtk/events/rest_spec.rb
|
162
158
|
- spec/mtk/events/timeline_spec.rb
|
163
159
|
- spec/mtk/groups/chord_spec.rb
|
164
160
|
- spec/mtk/groups/collection_spec.rb
|
@@ -193,34 +189,28 @@ files:
|
|
193
189
|
- spec/spec_helper.rb
|
194
190
|
- spec/test.mid
|
195
191
|
homepage: http://github.com/adamjmurray/mtk
|
196
|
-
licenses:
|
192
|
+
licenses:
|
193
|
+
- BSD
|
194
|
+
metadata: {}
|
197
195
|
post_install_message:
|
198
196
|
rdoc_options: []
|
199
197
|
require_paths:
|
200
198
|
- lib
|
201
199
|
required_ruby_version: !ruby/object:Gem::Requirement
|
202
|
-
none: false
|
203
200
|
requirements:
|
204
201
|
- - ! '>='
|
205
202
|
- !ruby/object:Gem::Version
|
206
203
|
version: '0'
|
207
|
-
segments:
|
208
|
-
- 0
|
209
|
-
hash: 1626364894868064054
|
210
204
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
-
none: false
|
212
205
|
requirements:
|
213
206
|
- - ! '>='
|
214
207
|
- !ruby/object:Gem::Version
|
215
208
|
version: '0'
|
216
|
-
segments:
|
217
|
-
- 0
|
218
|
-
hash: 1626364894868064054
|
219
209
|
requirements: []
|
220
210
|
rubyforge_project:
|
221
|
-
rubygems_version:
|
211
|
+
rubygems_version: 2.0.6
|
222
212
|
signing_key:
|
223
|
-
specification_version:
|
213
|
+
specification_version: 4
|
224
214
|
summary: Music Tool Kit for Ruby
|
225
215
|
test_files: []
|
226
216
|
has_rdoc:
|