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
@@ -1,35 +1,39 @@
1
1
  module MTK
2
2
 
3
- # A Set of PitchClasses, for 12-tone set-theory pitch analysis and manipulations
3
+ # An ordered Set of PitchClasses, for 12-tone set-theory pitch analysis and manipulations
4
4
  #
5
5
  class PitchClassSet
6
6
 
7
- include Mappable
7
+ include Helper::Collection
8
+ include Transform::Mappable
9
+ include Transform::Transposable
10
+ include Transform::Invertible
11
+ include Transform::SetTheoryOperations
8
12
 
9
13
  attr_reader :pitch_classes
10
-
11
- def initialize(pitch_classes)
12
- @pitch_classes = pitch_classes.to_a.uniq.sort.freeze
14
+
15
+ def self.random_row
16
+ new(PitchClasses::PITCH_CLASSES.shuffle)
13
17
  end
14
18
 
15
- def self.from_a enumerable
16
- new enumerable
19
+ def self.all
20
+ @all ||= new(PitchClasses::PITCH_CLASSES)
17
21
  end
18
22
 
19
- def to_a
20
- Array.new(@pitch_classes)
23
+ def initialize(pitch_classes)
24
+ @pitch_classes = pitch_classes.to_a.uniq.freeze
21
25
  end
22
26
 
23
- def each &block
24
- @pitch_classes.each &block
27
+ def elements
28
+ @pitch_classes
25
29
  end
26
30
 
27
- def size
28
- @pitch_classes.size
31
+ def self.from_a enumerable
32
+ new enumerable
29
33
  end
30
34
 
31
35
  def normal_order
32
- ordering = Array.new(@pitch_classes)
36
+ ordering = Array.new(@pitch_classes.sort)
33
37
  min_span, start_index_for_normal_order = nil, nil
34
38
 
35
39
  # check every rotation for the minimal span:
@@ -86,6 +90,22 @@ module MTK
86
90
  end
87
91
  end
88
92
 
93
+ # Compare for equality, ignoring order
94
+ # @param other [#pitch_classes, #to_a, #sort, Array]
95
+ def =~ other
96
+ if other.is_a? Array and other.frozen?
97
+ @pitch_classes.sort == other
98
+ elsif other.respond_to? :pitch_classes
99
+ @pitch_classes.sort == other.pitch_classes.sort
100
+ elsif other.respond_to? :to_a
101
+ @pitch_classes.sort == other.to_a.sort
102
+ elsif other.respond_to? :sort
103
+ @pitch_classes.sort == other.sort
104
+ else
105
+ @pitch_classes.sort == other
106
+ end
107
+ end
108
+
89
109
  def to_s
90
110
  @pitch_classes.join(' ')
91
111
  end
@@ -103,4 +123,16 @@ module MTK
103
123
  end
104
124
 
105
125
  end
126
+
127
+ # Construct a {PitchClassSet} from any supported type
128
+ def PitchClassSet(*anything)
129
+ anything = anything.first if anything.size == 1
130
+ case anything
131
+ when Array then PitchClassSet.new(anything.map{|elem| PitchClass(elem) })
132
+ when PitchClassSet then anything
133
+ else PitchClassSet.new([PitchClass(anything)])
134
+ end
135
+ end
136
+ module_function :PitchClassSet
137
+
106
138
  end
data/lib/mtk/pitch_set.rb CHANGED
@@ -4,7 +4,10 @@ module MTK
4
4
  #
5
5
  class PitchSet
6
6
 
7
- include Mappable
7
+ include Helper::Collection
8
+ include Transform::Mappable
9
+ include Transform::Transposable
10
+ include Transform::Invertible
8
11
 
9
12
  attr_reader :pitches
10
13
 
@@ -12,16 +15,12 @@ module MTK
12
15
  @pitches = pitches.to_a.uniq.sort.freeze
13
16
  end
14
17
 
15
- def self.from_a enumerable
16
- new enumerable
18
+ def elements
19
+ @pitches
17
20
  end
18
21
 
19
- def to_a
20
- Array.new(@pitches)
21
- end
22
-
23
- def each &block
24
- @pitches.each &block
22
+ def self.from_a enumerable
23
+ new enumerable
25
24
  end
26
25
 
27
26
  def to_pitch_class_set
@@ -32,18 +31,7 @@ module MTK
32
31
  @pitch_classes ||= @pitches.map{|p| p.pitch_class }.uniq
33
32
  end
34
33
 
35
- def + semitones
36
- each_pitch_apply :+, semitones
37
- end
38
-
39
- def - semitones
40
- each_pitch_apply :-, semitones
41
- end
42
-
43
- def invert(center_pitch=@pitches.first)
44
- each_pitch_apply :invert, center_pitch
45
- end
46
-
34
+ # generate a chord inversion (positive numbers move the lowest notes up an octave, negative moves the highest notes down)
47
35
  def inversion(number)
48
36
  number = number.to_i
49
37
  pitch_set = Array.new(@pitches)
@@ -61,12 +49,8 @@ module MTK
61
49
  self.class.new pitch_set
62
50
  end
63
51
 
64
- def include? pitch
65
- @pitches.include? pitch
66
- end
67
-
68
52
  def nearest(pitch_class)
69
- self + @pitches.first.pitch_class.distance_to(pitch_class)
53
+ self.transpose @pitches.first.pitch_class.distance_to(pitch_class)
70
54
  end
71
55
 
72
56
  # @param other [#pitches, #to_a, Array]
@@ -84,12 +68,17 @@ module MTK
84
68
  @pitches.inspect
85
69
  end
86
70
 
87
- #######################################
88
- protected
71
+ end
89
72
 
90
- def each_pitch_apply(method_name, *args, &block)
91
- self.class.new @pitches.map{|pitch| pitch.send(method_name, *args, &block) }
73
+ # Construct a {PitchSet} from any supported type
74
+ def PitchSet(*anything)
75
+ anything = anything.first if anything.size == 1
76
+ case anything
77
+ when Array then PitchSet.new(anything.map{|elem| Pitch(elem) })
78
+ when PitchSet then anything
79
+ else PitchSet.new([Pitch(anything)])
92
80
  end
93
-
94
81
  end
82
+ module_function :PitchSet
83
+
95
84
  end
@@ -0,0 +1,85 @@
1
+ module MTK
2
+ module Sequencer
3
+
4
+ # A Sequencer produces {Timeline}s from a collection of {Pattern}s.
5
+ #
6
+ # @abstract Subclass and override {#advance} to implement a Sequencer.
7
+ #
8
+ class AbstractSequencer
9
+
10
+ # The maximum number of [time,event_list] entries that will be generated for the {Timeline}.
11
+ # nil means no maximum (be careful of infinite loops!)
12
+ attr_accessor :max_steps
13
+
14
+ # The maximum time (key) that will be generated for the {Timeline}.
15
+ # nil means no maximum (be careful of infinite loops!)
16
+ attr_accessor :max_time
17
+
18
+ # Used by {#to_timeline} to builds event lists from the results of #{Pattern::Enumerator#next} for the {Pattern}s in this Sequencer.
19
+ attr_reader :event_builder
20
+
21
+ # The current time offset for the sequencer. Used for the {Timeline} times.
22
+ attr_reader :time
23
+
24
+ # The current sequencer step index (the number of times-1 that {#next} has been called), or -1 if the sequencer has not yet started.
25
+ attr_reader :step
26
+
27
+ def initialize(patterns, options={})
28
+ @patterns = patterns
29
+ @max_steps = options[:max_steps]
30
+ @max_time = options[:max_time]
31
+
32
+ event_builder_class = options.fetch :event_builder, Helper::EventBuilder
33
+ @event_builder = event_builder_class.new(patterns, options)
34
+ rewind
35
+ end
36
+
37
+
38
+ # Produce a {Timeline} from the {Pattern}s in this Sequencer.
39
+ def to_timeline
40
+ rewind
41
+ timeline = Timeline.new
42
+ loop do
43
+ events = self.next
44
+ timeline[@time] = events if events
45
+ end
46
+ timeline
47
+ end
48
+
49
+
50
+ # Advanced the step index and time, and return the next list of events built from the sequencer patterns.
51
+ # @note this is called automatically by {#to_timeline},
52
+ # so you can ignore this method unless you want to hack on sequencers at a lower level.
53
+ def next
54
+ if @step >= 0
55
+ advance!
56
+ raise StopIteration if @max_time and @time > @max_time
57
+ end
58
+ @step += 1
59
+ raise StopIteration if @max_steps and @step >= @max_steps
60
+ @event_builder.next
61
+ end
62
+
63
+
64
+ # Reset the sequencer and all its patterns.
65
+ # @note this is called automatically at the beginning of {#to_timeline},
66
+ # so you can ignore this method unless you want to hack on sequencers at a lower level.
67
+ def rewind
68
+ @time = 0
69
+ @step = -1
70
+ event_builder.rewind
71
+ end
72
+
73
+
74
+ ########################
75
+ protected
76
+
77
+ # Advance @time to the next time for the {Timeline} being produced by {#to_timeline}
78
+ def advance!
79
+ @time += 1 # default behavior simply advances one beat at a time
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ module MTK
2
+ module Sequencer
3
+
4
+ # A Sequencer which uses a :rhythm type {Pattern} to determine the delta times between entries in the {Timeline}.
5
+ class RhythmicSequencer < AbstractSequencer
6
+
7
+ def initialize(patterns, options={})
8
+ patterns = patterns.clone
9
+ patterns.each_with_index do |pattern, index|
10
+ if pattern.type == :rhythm
11
+ @rhythm = pattern
12
+ patterns.delete_at index # so we don't enumerate the rhythm values in EventBuilder
13
+ end
14
+ end
15
+ super(patterns, options)
16
+ end
17
+
18
+ ########################
19
+ protected
20
+
21
+ # (see AbstractSequencer#advance!)
22
+ def advance!
23
+ @time += @rhythm.next
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module MTK
2
+ module Sequencer
3
+
4
+ # A Sequencer which has a constant {#step_size} time between {Timeline} entries.
5
+ class StepSequencer < AbstractSequencer
6
+
7
+ # The time between entries in the {Timeline}.
8
+ attr_accessor :step_size
9
+
10
+ def initialize(patterns, options={})
11
+ super
12
+ @step_size = options.fetch :step_size, 1
13
+ end
14
+
15
+ ########################
16
+ protected
17
+
18
+ # (see AbstractSequencer#advance!)
19
+ def advance!
20
+ @time += @step_size
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
data/lib/mtk/timeline.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  module MTK
2
2
 
3
+ # A collection of timed events. The core data structure used to interface with input and output.
4
+ #
3
5
  # Maps sorted times to lists of events.
4
6
  #
5
- # Enumerable as |time,event| pairs.
7
+ # Enumerable as [time,event_list] pairs.
6
8
  #
7
9
  class Timeline
8
10
 
9
- include Mappable
11
+ include Transform::Mappable
10
12
 
11
13
  def initialize()
12
14
  @timeline = {}
@@ -90,37 +92,32 @@ module MTK
90
92
  end
91
93
 
92
94
  def each
93
- times.each do |time|
94
- events = @timeline[time]
95
- events.each do |event|
96
- yield time,event
97
- end
98
- end
99
- end
100
-
101
- def each_time
102
- times.each do |time|
103
- events = @timeline[time]
104
- yield time,events
95
+ # this is similar to @timeline.each, but by iterating over #times, we yield the events in chronological order
96
+ for time in times
97
+ yield time,@timeline[time]
105
98
  end
106
99
  end
107
100
 
108
101
  def map! &block
102
+ # we use the enumerable_map that aliased by the Mappable module,
103
+ # because Mappable#map will create an extra timeline instance, which is unnecessary in this case
109
104
  mapped = enumerable_map &block
110
105
  clear
111
106
  merge mapped
112
107
  end
113
108
 
109
+ # Map every individual event, without regard for the time at which is occurs
114
110
  def map_events
115
111
  mapped_timeline = Timeline.new
116
- each_time do |time,events|
112
+ for time,events in self
117
113
  mapped_timeline[time] = events.map{|event| yield event }
118
114
  end
119
115
  mapped_timeline
120
116
  end
121
117
 
118
+ # Map every individual event in place, without regard for the time at which is occurs
122
119
  def map_events!
123
- each_time do |time,events|
120
+ for time,events in self
124
121
  self[time] = events.map{|event| yield event }
125
122
  end
126
123
  end
@@ -135,18 +132,68 @@ module MTK
135
132
 
136
133
  def flatten
137
134
  flattened = Timeline.new
138
- for time,event in self
139
- if event.is_a? Timeline
140
- for subtime, subevent in event.flatten
141
- flattened.add(time+subtime, subevent)
135
+ for time,events in self
136
+ for event in events
137
+ if event.is_a? Timeline
138
+ for subtime,subevent in event.flatten
139
+ flattened.add(time+subtime, subevent)
140
+ end
141
+ else
142
+ flattened.add(time,event)
142
143
  end
143
- else
144
- flattened.add(time,event)
145
144
  end
146
145
  end
147
146
  flattened
148
147
  end
149
148
 
149
+ # @return a new Timeline where all times have been quantized to multiples of the given interval
150
+ # @example timeline.quantize(0.5) # quantize to eight notes (assuming the beat is a quarter note)
151
+ # @see quantize!
152
+ def quantize interval
153
+ map{|time,events| [self.class.quantize_time(time,interval), events] }
154
+ end
155
+
156
+ def quantize! interval
157
+ map!{|time,events| [self.class.quantize_time(time,interval), events] }
158
+ end
159
+
160
+ # shifts all times by the given amount
161
+ # @see #shift!
162
+ # @see #shift_to
163
+ def shift time_delta
164
+ map{|time,events| [time+time_delta, events] }
165
+ end
166
+
167
+ # shifts all times in place by the given amount
168
+ # @see #shift
169
+ # @see #shift_to!
170
+ def shift! time_delta
171
+ map!{|time,events| [time+time_delta, events] }
172
+ end
173
+
174
+ # shifts the times so that the start of the timeline is at the given time
175
+ # @see #shift_to!
176
+ # @see #shift
177
+ def shift_to absolute_time
178
+ start = times.first
179
+ if start
180
+ shift absolute_time - start
181
+ else
182
+ clone
183
+ end
184
+ end
185
+
186
+ # shifts the times in place so that the start of the timeline is at the given time
187
+ # @see #shift_to
188
+ # @see #shift!
189
+ def shift_to! absolute_time
190
+ start = times.first
191
+ if start
192
+ shift! absolute_time - start
193
+ end
194
+ self
195
+ end
196
+
150
197
  def to_s
151
198
  times.map{|t| "#{t} => #{@timeline[t].join ', '}" }.join "\n"
152
199
  end
@@ -155,6 +202,12 @@ module MTK
155
202
  @timeline.inspect
156
203
  end
157
204
 
205
+ def self.quantize_time time, interval
206
+ upper = interval * (time.to_f/interval).ceil
207
+ lower = upper - interval
208
+ (time - lower) < (upper - time) ? lower : upper
209
+ end
210
+
158
211
  end
159
212
 
160
213
  end
@@ -0,0 +1,15 @@
1
+ module MTK::Transform
2
+
3
+ # {Mappable} class whose elements can handle the :invert message
4
+ # @note Classes including this module should include either MTK::Collection or provide a #first method
5
+ module Invertible
6
+
7
+ # Invert all elements around the given inversion point
8
+ # @param inversion_point [Numeric] the value around which all elements will be inverted (defaults to the first element in the collection)
9
+ def invert(inversion_point=first)
10
+ map{|elem| elem.invert(inversion_point) }
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -1,14 +1,18 @@
1
- module MTK
1
+ module MTK::Transform
2
2
 
3
3
  # Similar to Enumerable, but relies on the including Class's from_a method to
4
- # provide an implementation of #map which returns an object of the same type
4
+ # provide an implementation of #map which returns an object of the same type.
5
5
  module Mappable
6
6
  include Enumerable
7
7
 
8
+ # the original Enumerable#map implementation, which returns an Array
8
9
  alias enumerable_map map
10
+
11
+ # the overriden #map implementation, which returns an object of the same type
9
12
  def map &block
10
13
  self.class.from_a(enumerable_map &block)
11
14
  end
12
15
 
13
16
  end
17
+
14
18
  end
@@ -0,0 +1,34 @@
1
+ module MTK::Transform
2
+
3
+ # {Helper::Collection} that supports set theory operations
4
+ module SetTheoryOperations
5
+
6
+ # the collection of elements present in both sets
7
+ def intersection(other)
8
+ self.class.from_a(to_a & other.to_a)
9
+ end
10
+
11
+ # the collection of all elements present in either set
12
+ def union(other)
13
+ self.class.from_a(to_a | other.to_a)
14
+ end
15
+
16
+ # the collection of elements from this set with any elements from the other set removed
17
+ def difference(other)
18
+ self.class.from_a(to_a - other.to_a)
19
+ end
20
+
21
+ # the collection of elements that are members of exactly one of the sets
22
+ def symmetric_difference(other)
23
+ union(other).difference( intersection(other) )
24
+ end
25
+
26
+ # the collection of elements that are not members of this set
27
+ # @note this method requires that the including class define the class method .all(), which returns the collection of all possible elements
28
+ def complement
29
+ self.class.all.difference(self)
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,14 @@
1
+ module MTK::Transform
2
+
3
+ # {Mappable} class whose elements can handle the :transpose message
4
+ module Transposable
5
+
6
+ # Transpose all elements upward by the given interval
7
+ # @param interval_in_semitones [Numeric] an interval in semitones
8
+ def transpose interval_in_semitones
9
+ map{|elem| elem + interval_in_semitones }
10
+ end
11
+
12
+ end
13
+
14
+ end
data/lib/mtk.rb CHANGED
@@ -1,4 +1,41 @@
1
- require 'mtk/util/mappable'
1
+ ##############################################
2
+ # Description of modules for documentation:
3
+
4
+ # The top level module for this library
5
+ module MTK
6
+
7
+ # Internal helper classes used to avoid duplicating code in this library.
8
+ module Helper
9
+ end
10
+
11
+ # Classes that emit elements one at a time. Used by {Sequencer}s to construct {Timeline}s.
12
+ #
13
+ # The core interface for Pattern classes is {Pattern::Enumerator#next} and {Pattern::Enumerator#rewind}.
14
+ module Pattern
15
+ end
16
+
17
+ # Classes that assemble {Pattern}s into {Timeline}s.
18
+ module Sequencer
19
+ end
20
+
21
+ # Optional classes for the "MTK language", which let's you compose music via MTK without writing any Ruby code
22
+ module Lang
23
+ end
24
+
25
+ # Optional classes for MIDI input and output.
26
+ module MIDI
27
+ end
28
+
29
+ end
30
+
31
+ require 'mtk/helper/collection'
32
+ require 'mtk/helper/pseudo_constants'
33
+
34
+ require 'mtk/transform/mappable'
35
+ require 'mtk/transform/transposable'
36
+ require 'mtk/transform/invertible'
37
+ require 'mtk/transform/set_theory_operations'
38
+
2
39
  require 'mtk/pitch_class'
3
40
  require 'mtk/pitch_class_set'
4
41
  require 'mtk/pitch'
@@ -6,31 +43,28 @@ require 'mtk/pitch_set'
6
43
 
7
44
  require 'mtk/event'
8
45
  require 'mtk/note'
9
- require 'mtk/chord'
10
46
  require 'mtk/timeline'
11
47
 
12
- require 'mtk/constants/pseudo_constants'
13
- require 'mtk/constants/pitch_classes'
14
- require 'mtk/constants/pitches'
15
- require 'mtk/constants/intervals'
16
- require 'mtk/constants/dynamics'
48
+ require 'mtk/_constants/pitch_classes'
49
+ require 'mtk/_constants/pitches'
50
+ require 'mtk/_constants/intervals'
51
+ require 'mtk/_constants/intensities'
52
+ require 'mtk/_constants/durations'
17
53
 
18
- require 'mtk/numeric_extensions'
54
+ require 'mtk/pattern/enumerator'
55
+ require 'mtk/pattern/abstract_pattern'
56
+ require 'mtk/pattern/sequence'
57
+ require 'mtk/pattern/cycle'
58
+ require 'mtk/pattern/choice'
59
+ require 'mtk/pattern/function'
60
+ require 'mtk/pattern/lines'
61
+ require 'mtk/pattern/palindrome'
19
62
 
63
+ require 'mtk/helper/event_builder'
64
+ require 'mtk/sequencer/abstract_sequencer'
65
+ require 'mtk/sequencer/step_sequencer'
66
+ require 'mtk/sequencer/rhythmic_sequencer'
20
67
 
21
- ##############################################
22
- # Description of modules for documentation:
68
+ require 'mtk/_numeric_extensions'
23
69
 
24
- # The top level module for this library
25
- module MTK
26
-
27
- # Classes for MIDI input and output
28
- module MIDI
29
- end
30
-
31
- # Classes that enumerate elements
32
- module Pattern
33
- end
34
-
35
- end
36
70