mtk 0.0.1 → 0.0.2

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 (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