mtk 0.0.1

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.
Files changed (45) hide show
  1. data/README.md +52 -0
  2. data/Rakefile +31 -0
  3. data/lib/mtk/chord.rb +47 -0
  4. data/lib/mtk/constants/dynamics.rb +56 -0
  5. data/lib/mtk/constants/intervals.rb +76 -0
  6. data/lib/mtk/constants/pitch_classes.rb +18 -0
  7. data/lib/mtk/constants/pitches.rb +24 -0
  8. data/lib/mtk/constants/pseudo_constants.rb +25 -0
  9. data/lib/mtk/event.rb +61 -0
  10. data/lib/mtk/midi/file.rb +179 -0
  11. data/lib/mtk/note.rb +44 -0
  12. data/lib/mtk/numeric_extensions.rb +61 -0
  13. data/lib/mtk/pattern/choice.rb +21 -0
  14. data/lib/mtk/pattern/note_sequence.rb +60 -0
  15. data/lib/mtk/pattern/pitch_sequence.rb +22 -0
  16. data/lib/mtk/pattern/sequence.rb +65 -0
  17. data/lib/mtk/patterns.rb +4 -0
  18. data/lib/mtk/pitch.rb +112 -0
  19. data/lib/mtk/pitch_class.rb +113 -0
  20. data/lib/mtk/pitch_class_set.rb +106 -0
  21. data/lib/mtk/pitch_set.rb +95 -0
  22. data/lib/mtk/timeline.rb +160 -0
  23. data/lib/mtk/util/mappable.rb +14 -0
  24. data/lib/mtk.rb +36 -0
  25. data/spec/mtk/chord_spec.rb +74 -0
  26. data/spec/mtk/constants/dynamics_spec.rb +94 -0
  27. data/spec/mtk/constants/intervals_spec.rb +140 -0
  28. data/spec/mtk/constants/pitch_classes_spec.rb +35 -0
  29. data/spec/mtk/constants/pitches_spec.rb +23 -0
  30. data/spec/mtk/event_spec.rb +120 -0
  31. data/spec/mtk/midi/file_spec.rb +208 -0
  32. data/spec/mtk/note_spec.rb +65 -0
  33. data/spec/mtk/numeric_extensions_spec.rb +102 -0
  34. data/spec/mtk/pattern/choice_spec.rb +21 -0
  35. data/spec/mtk/pattern/note_sequence_spec.rb +121 -0
  36. data/spec/mtk/pattern/pitch_sequence_spec.rb +47 -0
  37. data/spec/mtk/pattern/sequence_spec.rb +54 -0
  38. data/spec/mtk/pitch_class_set_spec.rb +103 -0
  39. data/spec/mtk/pitch_class_spec.rb +165 -0
  40. data/spec/mtk/pitch_set_spec.rb +163 -0
  41. data/spec/mtk/pitch_spec.rb +217 -0
  42. data/spec/mtk/timeline_spec.rb +234 -0
  43. data/spec/spec_helper.rb +7 -0
  44. data/spec/test.mid +0 -0
  45. metadata +97 -0
@@ -0,0 +1,234 @@
1
+ require 'spec_helper'
2
+
3
+ describe MTK::Timeline do
4
+
5
+ let(:note1) { Note.new(C4, p, 1) }
6
+ let(:note2) { Note.new(G4, f, 2) }
7
+ let(:timeline_raw_data) { { 0 => note1, 1 => [note1, note2] } }
8
+ let(:timeline_hash) { { 0 => [note1], 1 => [note1, note2] } }
9
+ let(:timeline) { Timeline.from_hash(timeline_raw_data) }
10
+
11
+ it "is Enumerable" do
12
+ Timeline.new.should be_a Enumerable
13
+ end
14
+
15
+ it "wraps lone values in arrays" do
16
+ Timeline.from_hash(timeline_raw_data).should == Timeline.from_hash(timeline_hash)
17
+ end
18
+
19
+ describe "from_hash" do
20
+ it "creates an empty timeline when the hash is empty" do
21
+ Timeline.from_hash({}).should be_empty
22
+ end
23
+
24
+ it "builds a Timeline from a map of times to single events" do
25
+ t = Timeline.from_hash({ 0 => note1, 1 => note2 })
26
+ t[0].should == [note1]
27
+ t[1].should == [note2]
28
+ end
29
+
30
+ it "builds a Timeline from a map of times to event lists" do
31
+ t = Timeline.from_hash({ 0 => [note1, note2], 1 => [note2] })
32
+ t[0].should == [note1, note2]
33
+ t[1].should == [note2]
34
+ end
35
+ end
36
+
37
+ describe "from_a" do
38
+ it "creates a timeline from an Enumerable"
39
+ end
40
+
41
+ describe "#to_hash" do
42
+ it "returns the underlying Hash" do
43
+ timeline.to_hash.should == timeline_hash
44
+ end
45
+ end
46
+
47
+ describe "#clear" do
48
+ it "clears the timeline" do
49
+ timeline.clear.should be_empty
50
+ end
51
+ end
52
+
53
+ describe "#merge" do
54
+ it "merges all the time,event pairs in the given Enumerable into this Timeline"
55
+ end
56
+
57
+ describe "#empty?" do
58
+ it "is true when the timeilne has no events" do
59
+ Timeline.new.empty?.should be_true
60
+ end
61
+ end
62
+
63
+ describe "#[]" do
64
+ it "returns an array of the event(s) at the timepoint" do
65
+ timeline[0].should == [note1]
66
+ timeline[1].should == [note1, note2]
67
+ end
68
+ it "returns nil when no events exist at the timepoint" do
69
+ timeline[3].should == nil
70
+ end
71
+ end
72
+
73
+ describe "#[]=" do
74
+ it "set a single event at the given timepoint" do
75
+ timeline[5] = note1
76
+ timeline[5].should == [note1]
77
+ end
78
+ it "set an array of events at the given timepoint" do
79
+ timeline[5] = [note1, note2]
80
+ timeline[5].should == [note1, note2]
81
+ end
82
+ it "replaces existing events at the timepoint" do
83
+ timeline[5] = note1
84
+ timeline[5] = note2
85
+ timeline[5].should == [note2]
86
+ end
87
+ end
88
+
89
+ describe "#add" do
90
+ it "creates a new event list at a previously empty timepoint" do
91
+ timeline.add(5, note1)
92
+ timeline[5].should == [note1]
93
+ end
94
+
95
+ it "appends to existing event lists" do
96
+ timeline.add(5, note1)
97
+ timeline.add(5, note2)
98
+ timeline[5].should == [note1, note2]
99
+ end
100
+
101
+ it "accepts either a single event or a list of events as its second argument"
102
+ end
103
+
104
+ describe "#delete" do
105
+ it "removes an event list at the given time" do
106
+ timeline.delete(1)
107
+ timeline.should == { 0 => [note1] }
108
+ end
109
+ end
110
+
111
+ describe "#has_time?" do
112
+ it "returns true if the time has been assigned" do
113
+ (timeline.has_time? 1).should be_true
114
+ end
115
+ it "returns false if the time doesn't exist" do
116
+ (timeline.has_time? 3).should be_false
117
+ end
118
+ end
119
+
120
+ describe "#times" do
121
+ it "is the sorted list of times" do
122
+ timeline.times.should == [0,1]
123
+ end
124
+ end
125
+
126
+ describe "#==" do
127
+ it "is true when the underlying Hashes are equal" do
128
+ timeline.should == Timeline.from_hash(timeline_hash)
129
+ end
130
+ it "is false when the underlying Hashes are not equal" do
131
+ timeline.should_not == Timeline.from_hash( {0 => [note2], 1 => [note1, note2]} )
132
+ end
133
+ it "allows for direct comparison to hashes" do
134
+ timeline.should == timeline_hash
135
+ end
136
+ end
137
+
138
+ describe "#events" do
139
+ it "is all events in a flattened array" do
140
+ timeline.events.should == [note1, note1, note2]
141
+ end
142
+ end
143
+
144
+ describe "#each" do
145
+ it "yields each |time,single_event| pair" do
146
+ yielded = []
147
+ timeline.each{|t,e| yielded << [t,e] }
148
+ yielded.should == [ [0,note1], [1,note1], [1,note2] ]
149
+ end
150
+ end
151
+
152
+ describe "#each_time" do
153
+ it "yields each |time,event_list| pair" do
154
+ yielded = []
155
+ timeline.each_time{|t,es| yielded << [t,es] }
156
+ yielded.should == [ [0,[note1]], [1,[note1,note2]] ]
157
+ end
158
+ end
159
+
160
+ describe "#map" do
161
+ it "returns a new Timeline where each [time,event] pair is replaced by the result of block" do
162
+ mapped = timeline.map{|time,event| [time+1, event.transpose(time+2)] }
163
+ mapped.should == { 1 => [note1.transpose(2)], 2 => [note1.transpose(3), note2.transpose(3)] }
164
+ end
165
+
166
+ it "does not modify this Timeline" do
167
+ timeline.map{|t,e| [0,nil] }
168
+ timeline.should == timeline_hash
169
+ end
170
+ end
171
+
172
+ describe "#map!" do
173
+ it "maps the Timeline in place" do
174
+ timeline.map! {|time,event| [time+1, event.transpose(time+2)] }
175
+ timeline.should == { 1 => [note1.transpose(2)], 2 => [note1.transpose(3), note2.transpose(3)] }
176
+ end
177
+ end
178
+
179
+ describe "#map_events" do
180
+ it "maps the Timeline in place" do
181
+ mapped = timeline.map_events {|event| event.transpose(1) }
182
+ mapped.should == { 0 => [note1.transpose(1)], 1=> [note1.transpose(1), note2.transpose(1)] }
183
+ end
184
+
185
+ it "does not modify this Timeline" do
186
+ timeline.map_events {|event| event.transpose(1) }
187
+ timeline.should == timeline_hash
188
+ end
189
+ end
190
+
191
+ describe "#map_events!" do
192
+ it "maps the Timeline in place" do
193
+ timeline.map_events! {|event| event.transpose(1) }
194
+ timeline.should == { 0 => [note1.transpose(1)], 1=> [note1.transpose(1), note2.transpose(1)] }
195
+ end
196
+ end
197
+
198
+ describe "#compact!" do
199
+ it "removes empty event lists" do
200
+ timeline[3] = []
201
+ timeline[4] = []
202
+ timeline.compact!
203
+ timeline.should == timeline_hash
204
+ end
205
+ end
206
+
207
+ describe "#flatten" do
208
+ it "flattens nested timelines so that all nested subtimes are converted to absolute times in a single timeline" do
209
+ timeline[10] = Timeline.from_hash({ 0 => note2, 1 => note1 })
210
+ timeline.flatten.should == timeline_hash.merge({ 10 => [note2], 11 => [note1] })
211
+ end
212
+
213
+ it "handles nested timelines which have nested timelines inside of them" do
214
+ nested = Timeline.from_hash({ 0 => note1 })
215
+ timeline[10] = Timeline.from_hash({ 100 => nested })
216
+ timeline.flatten.should == timeline_hash.merge({ 110 => [note1] })
217
+ end
218
+
219
+ it "returns a new Timeline" do
220
+ timeline.flatten.should_not equal(timeline)
221
+ end
222
+ end
223
+
224
+ describe "#clone" do
225
+ it "creates an equal Timeline" do
226
+ timeline.clone.should == timeline
227
+ end
228
+
229
+ it "returns a new instance" do
230
+ timeline.clone.should_not equal(timeline)
231
+ end
232
+ end
233
+ end
234
+
@@ -0,0 +1,7 @@
1
+ require 'mtk'
2
+ require 'mtk/patterns'
3
+ include MTK
4
+ include Pitches
5
+ include PitchClasses
6
+ include Dynamics
7
+ include Intervals
data/spec/test.mid ADDED
Binary file
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mtk
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Adam Murray
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-08 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description:
17
+ email: adam@compusition.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Rakefile
26
+ - README.md
27
+ - lib/mtk/chord.rb
28
+ - lib/mtk/constants/dynamics.rb
29
+ - lib/mtk/constants/intervals.rb
30
+ - lib/mtk/constants/pitch_classes.rb
31
+ - lib/mtk/constants/pitches.rb
32
+ - lib/mtk/constants/pseudo_constants.rb
33
+ - lib/mtk/event.rb
34
+ - lib/mtk/midi/file.rb
35
+ - lib/mtk/note.rb
36
+ - lib/mtk/numeric_extensions.rb
37
+ - lib/mtk/pattern/choice.rb
38
+ - lib/mtk/pattern/note_sequence.rb
39
+ - lib/mtk/pattern/pitch_sequence.rb
40
+ - lib/mtk/pattern/sequence.rb
41
+ - lib/mtk/patterns.rb
42
+ - lib/mtk/pitch.rb
43
+ - lib/mtk/pitch_class.rb
44
+ - lib/mtk/pitch_class_set.rb
45
+ - lib/mtk/pitch_set.rb
46
+ - lib/mtk/timeline.rb
47
+ - lib/mtk/util/mappable.rb
48
+ - lib/mtk.rb
49
+ - spec/mtk/chord_spec.rb
50
+ - spec/mtk/constants/dynamics_spec.rb
51
+ - spec/mtk/constants/intervals_spec.rb
52
+ - spec/mtk/constants/pitch_classes_spec.rb
53
+ - spec/mtk/constants/pitches_spec.rb
54
+ - spec/mtk/event_spec.rb
55
+ - spec/mtk/midi/file_spec.rb
56
+ - spec/mtk/note_spec.rb
57
+ - spec/mtk/numeric_extensions_spec.rb
58
+ - spec/mtk/pattern/choice_spec.rb
59
+ - spec/mtk/pattern/note_sequence_spec.rb
60
+ - spec/mtk/pattern/pitch_sequence_spec.rb
61
+ - spec/mtk/pattern/sequence_spec.rb
62
+ - spec/mtk/pitch_class_set_spec.rb
63
+ - spec/mtk/pitch_class_spec.rb
64
+ - spec/mtk/pitch_set_spec.rb
65
+ - spec/mtk/pitch_spec.rb
66
+ - spec/mtk/timeline_spec.rb
67
+ - spec/spec_helper.rb
68
+ - spec/test.mid
69
+ homepage: http://github.com/adamjmurray/mtk
70
+ licenses: []
71
+
72
+ post_install_message:
73
+ rdoc_options: []
74
+
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ requirements: []
90
+
91
+ rubyforge_project:
92
+ rubygems_version: 1.8.5
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: Musical ToolKit for Ruby
96
+ test_files: []
97
+