mtk 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.yardopts +9 -0
  2. data/INTRO.md +73 -0
  3. data/LICENSE.txt +27 -0
  4. data/README.md +93 -18
  5. data/Rakefile +13 -1
  6. data/examples/crescendo.rb +20 -0
  7. data/examples/dynamic_pattern.rb +39 -0
  8. data/examples/play_midi.rb +19 -0
  9. data/examples/print_midi.rb +13 -0
  10. data/examples/random_tone_row.rb +18 -0
  11. data/examples/tone_row_melody.rb +21 -0
  12. data/lib/mtk/_constants/durations.rb +80 -0
  13. data/lib/mtk/_constants/intensities.rb +81 -0
  14. data/lib/mtk/{constants → _constants}/intervals.rb +10 -1
  15. data/lib/mtk/_constants/pitch_classes.rb +35 -0
  16. data/lib/mtk/_constants/pitches.rb +49 -0
  17. data/lib/mtk/{numeric_extensions.rb → _numeric_extensions.rb} +0 -0
  18. data/lib/mtk/event.rb +14 -5
  19. data/lib/mtk/helper/collection.rb +114 -0
  20. data/lib/mtk/helper/event_builder.rb +85 -0
  21. data/lib/mtk/{constants → helper}/pseudo_constants.rb +7 -6
  22. data/lib/mtk/lang/grammar.rb +17 -0
  23. data/lib/mtk/lang/mtk_grammar.citrus +60 -0
  24. data/lib/mtk/midi/file.rb +10 -15
  25. data/lib/mtk/midi/jsound_input.rb +68 -0
  26. data/lib/mtk/midi/jsound_output.rb +80 -0
  27. data/lib/mtk/note.rb +22 -3
  28. data/lib/mtk/pattern/abstract_pattern.rb +132 -0
  29. data/lib/mtk/pattern/choice.rb +25 -9
  30. data/lib/mtk/pattern/cycle.rb +51 -0
  31. data/lib/mtk/pattern/enumerator.rb +26 -0
  32. data/lib/mtk/pattern/function.rb +46 -0
  33. data/lib/mtk/pattern/lines.rb +60 -0
  34. data/lib/mtk/pattern/palindrome.rb +42 -0
  35. data/lib/mtk/pattern/sequence.rb +15 -50
  36. data/lib/mtk/pitch.rb +45 -6
  37. data/lib/mtk/pitch_class.rb +36 -35
  38. data/lib/mtk/pitch_class_set.rb +46 -14
  39. data/lib/mtk/pitch_set.rb +20 -31
  40. data/lib/mtk/sequencer/abstract_sequencer.rb +85 -0
  41. data/lib/mtk/sequencer/rhythmic_sequencer.rb +29 -0
  42. data/lib/mtk/sequencer/step_sequencer.rb +26 -0
  43. data/lib/mtk/timeline.rb +75 -22
  44. data/lib/mtk/transform/invertible.rb +15 -0
  45. data/lib/mtk/{util → transform}/mappable.rb +6 -2
  46. data/lib/mtk/transform/set_theory_operations.rb +34 -0
  47. data/lib/mtk/transform/transposable.rb +14 -0
  48. data/lib/mtk.rb +56 -22
  49. data/spec/mtk/_constants/durations_spec.rb +118 -0
  50. data/spec/mtk/{constants/dynamics_spec.rb → _constants/intensities_spec.rb} +48 -17
  51. data/spec/mtk/{constants → _constants}/intervals_spec.rb +21 -0
  52. data/spec/mtk/_constants/pitch_classes_spec.rb +58 -0
  53. data/spec/mtk/_constants/pitches_spec.rb +52 -0
  54. data/spec/mtk/{numeric_extensions_spec.rb → _numeric_extensions_spec.rb} +0 -0
  55. data/spec/mtk/event_spec.rb +19 -0
  56. data/spec/mtk/helper/collection_spec.rb +291 -0
  57. data/spec/mtk/helper/event_builder_spec.rb +92 -0
  58. data/spec/mtk/helper/pseudo_constants_spec.rb +20 -0
  59. data/spec/mtk/lang/grammar_spec.rb +100 -0
  60. data/spec/mtk/midi/file_spec.rb +41 -6
  61. data/spec/mtk/note_spec.rb +53 -3
  62. data/spec/mtk/pattern/abstract_pattern_spec.rb +45 -0
  63. data/spec/mtk/pattern/choice_spec.rb +89 -3
  64. data/spec/mtk/pattern/cycle_spec.rb +133 -0
  65. data/spec/mtk/pattern/function_spec.rb +133 -0
  66. data/spec/mtk/pattern/lines_spec.rb +93 -0
  67. data/spec/mtk/pattern/note_cycle_spec.rb.bak +116 -0
  68. data/spec/mtk/pattern/palindrome_spec.rb +124 -0
  69. data/spec/mtk/pattern/pitch_cycle_spec.rb.bak +47 -0
  70. data/spec/mtk/pattern/pitch_sequence_spec.rb.bak +37 -0
  71. data/spec/mtk/pattern/sequence_spec.rb +128 -31
  72. data/spec/mtk/pitch_class_set_spec.rb +240 -7
  73. data/spec/mtk/pitch_class_spec.rb +84 -18
  74. data/spec/mtk/pitch_set_spec.rb +45 -10
  75. data/spec/mtk/pitch_spec.rb +59 -0
  76. data/spec/mtk/sequencer/abstract_sequencer_spec.rb +159 -0
  77. data/spec/mtk/sequencer/rhythmic_sequencer_spec.rb +49 -0
  78. data/spec/mtk/sequencer/step_sequencer_spec.rb +71 -0
  79. data/spec/mtk/timeline_spec.rb +118 -15
  80. data/spec/spec_helper.rb +4 -3
  81. metadata +59 -22
  82. data/lib/mtk/chord.rb +0 -47
  83. data/lib/mtk/constants/dynamics.rb +0 -56
  84. data/lib/mtk/constants/pitch_classes.rb +0 -18
  85. data/lib/mtk/constants/pitches.rb +0 -24
  86. data/lib/mtk/pattern/note_sequence.rb +0 -60
  87. data/lib/mtk/pattern/pitch_sequence.rb +0 -22
  88. data/lib/mtk/patterns.rb +0 -4
  89. data/spec/mtk/chord_spec.rb +0 -74
  90. data/spec/mtk/constants/pitch_classes_spec.rb +0 -35
  91. data/spec/mtk/constants/pitches_spec.rb +0 -23
  92. data/spec/mtk/pattern/note_sequence_spec.rb +0 -121
  93. data/spec/mtk/pattern/pitch_sequence_spec.rb +0 -47
@@ -8,6 +8,15 @@ describe MTK::Timeline do
8
8
  let(:timeline_hash) { { 0 => [note1], 1 => [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] } }
12
+ let(:unquantized_timeline) { Timeline.from_hash(unquantized_data) }
13
+ let(:quantization_interval) { 0.5 }
14
+ let(:quantized_data) { { 0.0 => [note1], 0.5 => [note1], 1.0 => [note1], 1.5 => [note1] } }
15
+
16
+ let(:shifted_data) { { 5 => [note1], 6 => [note1, note2] } }
17
+ let(:reverse_shifted_data) { { -5 => [note1], -4 => [note1, note2] } }
18
+ let(:shift_amount) { 5 }
19
+
11
20
  it "is Enumerable" do
12
21
  Timeline.new.should be_a Enumerable
13
22
  end
@@ -35,7 +44,9 @@ describe MTK::Timeline do
35
44
  end
36
45
 
37
46
  describe "from_a" do
38
- it "creates a timeline from an Enumerable"
47
+ it "creates a timeline from an Enumerable" do
48
+ Timeline.from_a(timeline_hash.to_a).should == timeline
49
+ end
39
50
  end
40
51
 
41
52
  describe "#to_hash" do
@@ -51,7 +62,9 @@ describe MTK::Timeline do
51
62
  end
52
63
 
53
64
  describe "#merge" do
54
- it "merges all the time,event pairs in the given Enumerable into this Timeline"
65
+ it "merges all the time,event pairs in the given Enumerable into this Timeline" do
66
+ timeline.merge({ 3 => note2 }).should == Timeline.from_hash( timeline_raw_data.merge({ 3 => note2 }) )
67
+ end
55
68
  end
56
69
 
57
70
  describe "#empty?" do
@@ -98,7 +111,10 @@ describe MTK::Timeline do
98
111
  timeline[5].should == [note1, note2]
99
112
  end
100
113
 
101
- it "accepts either a single event or a list of events as its second argument"
114
+ it "accepts a list of events as its second argument" do
115
+ timeline.add 5, [note1, note2]
116
+ timeline[5].should == [note1, note2]
117
+ end
102
118
  end
103
119
 
104
120
  describe "#delete" do
@@ -142,24 +158,16 @@ describe MTK::Timeline do
142
158
  end
143
159
 
144
160
  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
161
  it "yields each |time,event_list| pair" do
154
162
  yielded = []
155
- timeline.each_time{|t,es| yielded << [t,es] }
163
+ timeline.each{|time,events| yielded << [time,events] }
156
164
  yielded.should == [ [0,[note1]], [1,[note1,note2]] ]
157
165
  end
158
166
  end
159
167
 
160
168
  describe "#map" do
161
169
  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)] }
170
+ mapped = timeline.map{|time,events| [time+1, events.map{|e| e.transpose(time+2) }] }
163
171
  mapped.should == { 1 => [note1.transpose(2)], 2 => [note1.transpose(3), note2.transpose(3)] }
164
172
  end
165
173
 
@@ -171,7 +179,7 @@ describe MTK::Timeline do
171
179
 
172
180
  describe "#map!" do
173
181
  it "maps the Timeline in place" do
174
- timeline.map! {|time,event| [time+1, event.transpose(time+2)] }
182
+ timeline.map! {|time,events| [time+1, events.map{|e| e.transpose(time+2) }] }
175
183
  timeline.should == { 1 => [note1.transpose(2)], 2 => [note1.transpose(3), note2.transpose(3)] }
176
184
  end
177
185
  end
@@ -203,7 +211,86 @@ describe MTK::Timeline do
203
211
  timeline.should == timeline_hash
204
212
  end
205
213
  end
206
-
214
+
215
+ describe "#quantize" do
216
+ it "maps all times to the nearest multiple of the given interval" do
217
+ unquantized_timeline.quantize(quantization_interval).should == quantized_data
218
+ end
219
+ it "returns a new Timeline and does not modify the original" do
220
+ unquantized_timeline.quantize(quantization_interval)
221
+ unquantized_timeline.should == unquantized_data
222
+ end
223
+ end
224
+
225
+ describe "#quantize!" do
226
+ it "maps all times to the nearest multiple of the given interval" do
227
+ unquantized_timeline.quantize!(quantization_interval).should == quantized_data
228
+ end
229
+
230
+ it "modifies the Timeline in place" do
231
+ unquantized_timeline.quantize!(quantization_interval)
232
+ unquantized_timeline.should == quantized_data
233
+ end
234
+ end
235
+
236
+ describe "#shift" do
237
+ it "shifts all times by the given amount" do
238
+ timeline.shift(shift_amount).should == shifted_data
239
+ end
240
+
241
+ it "goes back in time for negative arguments" do
242
+ timeline.shift(-shift_amount).should == reverse_shifted_data
243
+ end
244
+
245
+ it "returns an instance of the same type" do
246
+ timeline.shift(shift_amount).should be_a timeline.class
247
+ end
248
+
249
+ it "returns a new Timeline and does not modify the original" do
250
+ timeline.shift(shift_amount).should_not equal timeline
251
+ end
252
+ end
253
+
254
+ describe "#shift!" do
255
+ it "shifts all times by the given amount" do
256
+ timeline.shift!(shift_amount).should == shifted_data
257
+ end
258
+
259
+ it "goes back in time for negative arguments" do
260
+ timeline.shift!(-shift_amount).should == reverse_shifted_data
261
+ end
262
+
263
+ it "modifies the timeline in place" do
264
+ timeline.shift!(shift_amount).should equal timeline
265
+ end
266
+ end
267
+
268
+ describe "#shift_to" do
269
+ it "shifts so the start is at the given time" do
270
+ Timeline.from_hash(shifted_data).shift_to(0).should == timeline
271
+ Timeline.from_hash(reverse_shifted_data).shift_to(0).should == timeline
272
+ end
273
+
274
+ it "returns an instance of the same type" do
275
+ timeline.shift_to(shift_amount).should be_a timeline.class
276
+ end
277
+
278
+ it "returns a new Timeline and does not modify the original" do
279
+ timeline.shift_to(shift_amount).should_not equal timeline
280
+ end
281
+ end
282
+
283
+ describe "#shift_to!" do
284
+ it "shifts so the start is at the given time" do
285
+ Timeline.from_hash(shifted_data).shift_to!(0).should == timeline
286
+ Timeline.from_hash(reverse_shifted_data).shift_to!(0).should == timeline
287
+ end
288
+
289
+ it "modifies the timeline in place" do
290
+ timeline.shift_to!(shift_amount).should equal timeline
291
+ end
292
+ end
293
+
207
294
  describe "#flatten" do
208
295
  it "flattens nested timelines so that all nested subtimes are converted to absolute times in a single timeline" do
209
296
  timeline[10] = Timeline.from_hash({ 0 => note2, 1 => note1 })
@@ -230,5 +317,21 @@ describe MTK::Timeline do
230
317
  timeline.clone.should_not equal(timeline)
231
318
  end
232
319
  end
320
+
321
+ describe ".quantize_time" do
322
+ it "takes a time and an interval, and returns the nearest multiple of the interval to the time" do
323
+ Timeline.quantize_time(23,10).should == 20
324
+ Timeline.quantize_time(27,10).should == 30
325
+ Timeline.quantize_time(30,10).should == 30
326
+ end
327
+
328
+ it "rounds up when exactly between 2 intervals" do
329
+ Timeline.quantize_time(25,10).should == 30
330
+ end
331
+
332
+ it "handles fractional intervals" do
333
+ Timeline.quantize_time(13,2.5).should == 12.5
334
+ end
335
+ end
233
336
  end
234
337
 
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require 'mtk'
2
- require 'mtk/patterns'
3
2
  include MTK
4
- include Pitches
5
3
  include PitchClasses
6
- include Dynamics
4
+ include Pitches
5
+ include Intensities
6
+ include Durations
7
7
  include Intervals
8
+
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mtk
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Adam Murray
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-08 00:00:00 Z
13
+ date: 2011-07-09 00:00:00 Z
14
14
  dependencies: []
15
15
 
16
16
  description:
@@ -23,49 +23,86 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - Rakefile
26
+ - INTRO.md
26
27
  - 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
28
+ - LICENSE.txt
29
+ - .yardopts
30
+ - lib/mtk/_constants/durations.rb
31
+ - lib/mtk/_constants/intensities.rb
32
+ - lib/mtk/_constants/intervals.rb
33
+ - lib/mtk/_constants/pitch_classes.rb
34
+ - lib/mtk/_constants/pitches.rb
35
+ - lib/mtk/_numeric_extensions.rb
33
36
  - lib/mtk/event.rb
37
+ - lib/mtk/helper/collection.rb
38
+ - lib/mtk/helper/event_builder.rb
39
+ - lib/mtk/helper/pseudo_constants.rb
40
+ - lib/mtk/lang/grammar.rb
41
+ - lib/mtk/lang/mtk_grammar.citrus
34
42
  - lib/mtk/midi/file.rb
43
+ - lib/mtk/midi/jsound_input.rb
44
+ - lib/mtk/midi/jsound_output.rb
35
45
  - lib/mtk/note.rb
36
- - lib/mtk/numeric_extensions.rb
46
+ - lib/mtk/pattern/abstract_pattern.rb
37
47
  - lib/mtk/pattern/choice.rb
38
- - lib/mtk/pattern/note_sequence.rb
39
- - lib/mtk/pattern/pitch_sequence.rb
48
+ - lib/mtk/pattern/cycle.rb
49
+ - lib/mtk/pattern/enumerator.rb
50
+ - lib/mtk/pattern/function.rb
51
+ - lib/mtk/pattern/lines.rb
52
+ - lib/mtk/pattern/palindrome.rb
40
53
  - lib/mtk/pattern/sequence.rb
41
- - lib/mtk/patterns.rb
42
54
  - lib/mtk/pitch.rb
43
55
  - lib/mtk/pitch_class.rb
44
56
  - lib/mtk/pitch_class_set.rb
45
57
  - lib/mtk/pitch_set.rb
58
+ - lib/mtk/sequencer/abstract_sequencer.rb
59
+ - lib/mtk/sequencer/rhythmic_sequencer.rb
60
+ - lib/mtk/sequencer/step_sequencer.rb
46
61
  - lib/mtk/timeline.rb
47
- - lib/mtk/util/mappable.rb
62
+ - lib/mtk/transform/invertible.rb
63
+ - lib/mtk/transform/mappable.rb
64
+ - lib/mtk/transform/set_theory_operations.rb
65
+ - lib/mtk/transform/transposable.rb
48
66
  - 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
67
+ - spec/mtk/_constants/durations_spec.rb
68
+ - spec/mtk/_constants/intensities_spec.rb
69
+ - spec/mtk/_constants/intervals_spec.rb
70
+ - spec/mtk/_constants/pitch_classes_spec.rb
71
+ - spec/mtk/_constants/pitches_spec.rb
72
+ - spec/mtk/_numeric_extensions_spec.rb
54
73
  - spec/mtk/event_spec.rb
74
+ - spec/mtk/helper/collection_spec.rb
75
+ - spec/mtk/helper/event_builder_spec.rb
76
+ - spec/mtk/helper/pseudo_constants_spec.rb
77
+ - spec/mtk/lang/grammar_spec.rb
55
78
  - spec/mtk/midi/file_spec.rb
56
79
  - spec/mtk/note_spec.rb
57
- - spec/mtk/numeric_extensions_spec.rb
80
+ - spec/mtk/pattern/abstract_pattern_spec.rb
58
81
  - spec/mtk/pattern/choice_spec.rb
59
- - spec/mtk/pattern/note_sequence_spec.rb
60
- - spec/mtk/pattern/pitch_sequence_spec.rb
82
+ - spec/mtk/pattern/cycle_spec.rb
83
+ - spec/mtk/pattern/function_spec.rb
84
+ - spec/mtk/pattern/lines_spec.rb
85
+ - spec/mtk/pattern/note_cycle_spec.rb.bak
86
+ - spec/mtk/pattern/palindrome_spec.rb
87
+ - spec/mtk/pattern/pitch_cycle_spec.rb.bak
88
+ - spec/mtk/pattern/pitch_sequence_spec.rb.bak
61
89
  - spec/mtk/pattern/sequence_spec.rb
62
90
  - spec/mtk/pitch_class_set_spec.rb
63
91
  - spec/mtk/pitch_class_spec.rb
64
92
  - spec/mtk/pitch_set_spec.rb
65
93
  - spec/mtk/pitch_spec.rb
94
+ - spec/mtk/sequencer/abstract_sequencer_spec.rb
95
+ - spec/mtk/sequencer/rhythmic_sequencer_spec.rb
96
+ - spec/mtk/sequencer/step_sequencer_spec.rb
66
97
  - spec/mtk/timeline_spec.rb
67
98
  - spec/spec_helper.rb
68
99
  - 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
69
106
  homepage: http://github.com/adamjmurray/mtk
70
107
  licenses: []
71
108
 
@@ -92,6 +129,6 @@ rubyforge_project:
92
129
  rubygems_version: 1.8.5
93
130
  signing_key:
94
131
  specification_version: 3
95
- summary: Musical ToolKit for Ruby
132
+ summary: Music ToolKit for Ruby
96
133
  test_files: []
97
134
 
data/lib/mtk/chord.rb DELETED
@@ -1,47 +0,0 @@
1
- module MTK
2
-
3
- # A multi-pitch, note-like {Event} defined by a {PitchSet}, intensity, and duration
4
- class Chord < Event
5
-
6
- # the {PitchSet} of the chord
7
- attr_reader :pitch_set
8
-
9
- def initialize(pitches, intensity, duration)
10
- @pitch_set = if pitches.is_a? PitchSet
11
- pitches
12
- else
13
- PitchSet.new(pitches)
14
- end
15
- super(intensity, duration)
16
- end
17
-
18
- def self.from_hash(hash)
19
- new hash[:pitch_set], hash[:intensity], hash[:duration]
20
- end
21
-
22
- def to_hash
23
- super.merge({ :pitch_set => @pitch_set })
24
- end
25
-
26
- def pitches
27
- @pitch_set.pitches
28
- end
29
-
30
- def transpose(interval)
31
- self.class.new(@pitch_set + interval, @intensity, @duration)
32
- end
33
-
34
- def == other
35
- super and other.respond_to? :pitch_set and @pitch_set == other.pitch_set
36
- end
37
-
38
- def to_s
39
- "Chord(#{pitch_set}, #{super})"
40
- end
41
-
42
- def inspect
43
- "Chord(#{pitch_set}, #{super})"
44
- end
45
- end
46
-
47
- end
@@ -1,56 +0,0 @@
1
- module MTK
2
-
3
- # Defines values for standard dynamic symbols.
4
- #
5
- # These can be thought of like constants, but in order to distinguish 'f' (forte) from the {PitchClass} 'F'
6
- # it was necessary to use lower-case names and therefore define them as "pseudo constant" methods.
7
- # The methods are available either throught the module (MTK::Dynamics::f) or via mixin (include MTK::Dynamics; f)
8
- #
9
- # These values are intensities in the range 0.0 - 1.0, so they can be easily scaled (unlike MIDI velocities).
10
- #
11
- # @note Including this module shadows Ruby's built-in p() method.
12
- # If you include this module, you can access the built-in p() method via Kernel.p()
13
- #
14
- # @see Note
15
- module Dynamics
16
- extend MTK::PseudoConstants
17
-
18
- # NOTE: the yard doc macros here only fill in [$2] with the actual value when generating docs under Ruby 1.9+
19
-
20
- # pianississimo
21
- # @macro [attach] dynamics.define_constant
22
- # @attribute [r]
23
- # @return [$2] intensity value for $1
24
- define_constant 'ppp', 0.125
25
-
26
- # pianissimo
27
- define_constant 'pp', 0.25
28
-
29
- # piano
30
- # @note Including this module shadows Ruby's built-in p() method.
31
- # If you include this module, you can access the built-in p() method via Kernel.p()
32
- define_constant 'p', 0.375
33
-
34
- # mezzo-piano
35
- define_constant 'mp', 0.5
36
-
37
- # mezzo-forte
38
- define_constant 'mf', 0.625
39
-
40
- # forte
41
- define_constant 'f', 0.75
42
-
43
- # fortissimo
44
- define_constant 'ff', 0.875
45
-
46
- # fortississimo
47
- define_constant 'fff', 1.0
48
-
49
- def self.[](name)
50
- send name
51
- rescue
52
- nil
53
- end
54
-
55
- end
56
- end
@@ -1,18 +0,0 @@
1
- module MTK
2
-
3
- # Defines a constant for each {PitchClass} in the Western chromatic scale.
4
-
5
- module PitchClasses
6
-
7
- # An array of all pitch class constants defined in this module
8
- PITCH_CLASSES = []
9
-
10
- for name in PitchClass::NAMES
11
- pc = PitchClass.from_name name
12
- PITCH_CLASSES << pc
13
- const_set name, pc
14
- end
15
-
16
- end
17
-
18
- end
@@ -1,24 +0,0 @@
1
- module MTK
2
-
3
- # Defines a constants for each {Pitch} in the standard MIDI range using scientific pitch notation.
4
- #
5
- # See http://en.wikipedia.org/wiki/Scientific_pitch_notation
6
- #
7
- # Note that because the character '#' cannot be used in the name of a constant,
8
- # The "black key" pitches are all named as flats with 'b' (for example, Gb3 or Cb4)
9
-
10
- module Pitches
11
-
12
- # An array of all the pitch constants defined in this module
13
- PITCHES = []
14
-
15
- 128.times do |note_number|
16
- pitch = Pitch.from_i( note_number )
17
- PITCHES << pitch
18
- octave_str = pitch.octave.to_s.sub(/-/,'_') # '_1' for -1
19
- const_set "#{pitch.pitch_class}#{octave_str}", pitch
20
- end
21
-
22
- end
23
-
24
- end
@@ -1,60 +0,0 @@
1
- module MTK
2
- module Pattern
3
-
4
- # A {Sequence} of {Note}s
5
- class NoteSequence
6
-
7
- attr_reader :pitch_sequence, :intensity_sequence, :duration_sequence
8
-
9
- attr_accessor :pitch, :intensity, :duration
10
-
11
- def initialize(pitches, intensities=nil, durations=nil, defaults={})
12
- @pitch_sequence = PitchSequence.new(pitches)
13
- @intensity_sequence = Sequence.new(intensities)
14
- @duration_sequence = Sequence.new(durations)
15
- @default = {:pitch => Pitches::C4, :intensity => Dynamics::mf, :duration => 1}.merge defaults
16
- reset
17
- end
18
-
19
- def pitches
20
- @pitch_sequence.elements
21
- end
22
-
23
- def intensities
24
- @intensity_sequence.elements
25
- end
26
-
27
- def durations
28
- @duration_sequence.elements
29
- end
30
-
31
- # reset the Sequence to the beginning
32
- def reset
33
- @pitch_sequence.reset
34
- @intensity_sequence.reset
35
- @duration_sequence.reset
36
-
37
- @pitch = @default[:pitch]
38
- @intensity = @default[:intensity]
39
- @duration = @default[:duration]
40
- end
41
-
42
- # return next {Note} in sequence
43
- def next
44
- @pitch = @pitch_sequence.next || @pitch
45
- @intensity = @intensity_sequence.next || @intensity
46
- @duration = @duration_sequence.next || @duration
47
-
48
-
49
- case @pitch
50
- when PitchSet,Array then Chord.new(@pitch, @intensity, @duration)
51
- else Note.new(@pitch, @intensity, @duration)
52
- end
53
- end
54
-
55
- end
56
-
57
- end
58
- end
59
-
60
-
@@ -1,22 +0,0 @@
1
- module MTK
2
- module Pattern
3
-
4
- # A {Sequence} of pitch-related elements, which may be {Pitch}es, {PitchClass}es, {PitchSet}s, or {Intervals} (Numeric)
5
- class PitchSequence < Sequence
6
-
7
- protected
8
-
9
- # extend value_of to handle intervals and PitchClasses
10
- def value_of element
11
- element = super # eval Procs
12
- case element
13
- when Numeric then @value + element if @value # add interval
14
- when PitchClass then @value.nearest(element) if @value
15
- else element
16
- end
17
- end
18
-
19
- end
20
-
21
- end
22
- end
data/lib/mtk/patterns.rb DELETED
@@ -1,4 +0,0 @@
1
- require 'mtk/pattern/sequence'
2
- require 'mtk/pattern/pitch_sequence'
3
- require 'mtk/pattern/note_sequence'
4
- require 'mtk/pattern/choice'
@@ -1,74 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe MTK::Chord do
4
-
5
- let(:pitch_set) { PitchSet.new [C4, E4, G4] }
6
- let(:intensity) { mf }
7
- let(:duration) { 2.5 }
8
- let(:chord) { Chord.new(pitch_set, intensity, duration) }
9
-
10
- it "can be constructed with a PitchSet" do
11
- pitch_set = PitchSet.new([C4])
12
- Chord.new( pitch_set, intensity, duration ).pitch_set.should == pitch_set
13
- end
14
-
15
- it "can be constructed with an Array of Pitches" do
16
- Chord.new( [C4], intensity, duration ).pitch_set.should == PitchSet.new([C4])
17
- end
18
-
19
- describe "#pitch_set" do
20
- it "is the pitch_set used to create the Chord" do
21
- chord.pitch_set.should == pitch_set
22
- end
23
-
24
- it "is a read-only attribute" do
25
- lambda{ chord.pitch_set = PitchSet.new }.should raise_error
26
- end
27
- end
28
-
29
- describe "#pitches" do
30
- it "is the list of pitches in the pitch_set" do
31
- chord.pitches.should == chord.pitch_set.pitches
32
- end
33
- end
34
-
35
- describe "from_hash" do
36
- it "constructs a Chord using a hash" do
37
- Chord.from_hash({ :pitch_set => pitch_set, :intensity => intensity, :duration => duration }).should == chord
38
- end
39
- end
40
-
41
- describe "#to_hash" do
42
- it "is a hash containing all the attributes of the Chord" do
43
- chord.to_hash.should == { :pitch_set => pitch_set, :intensity => intensity, :duration => duration }
44
- end
45
- end
46
-
47
- describe '#transpose' do
48
- it 'adds the given interval to the @pitch_set' do
49
- (chord.transpose 2.semitones).should == Chord.new(pitch_set+2, intensity, duration)
50
- end
51
- it 'does not affect the immutability of the Chord' do
52
- (chord.transpose 2.semitones).should_not == chord
53
- end
54
- end
55
-
56
- describe "#==" do
57
- it "is true when the pitch_sets, intensities, and durations are equal" do
58
- chord.should == Chord.new(pitch_set, intensity, duration)
59
- end
60
-
61
- it "is false when the pitch_sets are not equal" do
62
- chord.should_not == Chord.new(pitch_set + 1, intensity, duration)
63
- end
64
-
65
- it "is false when the intensities are not equal" do
66
- chord.should_not == Chord.new(pitch_set, intensity * 0.5, duration)
67
- end
68
-
69
- it "is false when the durations are not equal" do
70
- chord.should_not == Chord.new(pitch_set, intensity, duration * 2)
71
- end
72
- end
73
-
74
- end
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe MTK::PitchClasses do
4
- let(:cases) {
5
- [
6
- [PitchClasses::C, 'C', 0],
7
- [PitchClasses::Db, 'Db', 1],
8
- [PitchClasses::D, 'D', 2],
9
- [PitchClasses::Eb, 'Eb', 3],
10
- [PitchClasses::E, 'E', 4],
11
- [PitchClasses::F, 'F', 5],
12
- [PitchClasses::Gb, 'Gb', 6],
13
- [PitchClasses::G, 'G', 7],
14
- [PitchClasses::Ab, 'Ab', 8],
15
- [PitchClasses::A, 'A', 9],
16
- [PitchClasses::Bb, 'Bb', 10],
17
- [PitchClasses::B, 'B', 11],
18
- ]
19
- }
20
-
21
- it "defines constants for the 12 pitch classes in the twelve-tone octave" do
22
- cases.length.should == 12
23
- cases.each do |const, name, int_value|
24
- const.name.should == name
25
- const.to_i.should == int_value
26
- end
27
- end
28
-
29
- describe "PITCH_CLASSES" do
30
- it "contains the 12 pitch class constants" do
31
- PitchClasses::PITCH_CLASSES.length.should == 12
32
- PitchClasses::PITCH_CLASSES.should == cases.map{ |const,_,__| const }
33
- end
34
- end
35
- end