mtk 0.0.3.2 → 0.0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/.yardopts +2 -2
  2. data/DEVELOPMENT_NOTES.md +20 -0
  3. data/README.md +9 -3
  4. data/Rakefile +47 -13
  5. data/bin/mtk +55 -20
  6. data/examples/crescendo.rb +4 -4
  7. data/examples/{drum_pattern1.rb → drum_pattern.rb} +8 -8
  8. data/examples/dynamic_pattern.rb +5 -5
  9. data/examples/gets_and_play.rb +3 -2
  10. data/examples/notation.rb +3 -3
  11. data/examples/play_midi.rb +4 -4
  12. data/examples/print_midi.rb +2 -2
  13. data/examples/random_tone_row.rb +3 -3
  14. data/examples/syntax_to_midi.rb +2 -2
  15. data/examples/test_output.rb +4 -5
  16. data/examples/tone_row_melody.rb +7 -5
  17. data/lib/mtk/core/duration.rb +213 -0
  18. data/lib/mtk/core/intensity.rb +158 -0
  19. data/lib/mtk/core/interval.rb +157 -0
  20. data/lib/mtk/core/pitch.rb +154 -0
  21. data/lib/mtk/core/pitch_class.rb +194 -0
  22. data/lib/mtk/events/event.rb +4 -4
  23. data/lib/mtk/events/note.rb +12 -12
  24. data/lib/mtk/events/timeline.rb +232 -0
  25. data/lib/mtk/groups/chord.rb +56 -0
  26. data/lib/mtk/{helpers → groups}/collection.rb +33 -1
  27. data/lib/mtk/groups/melody.rb +96 -0
  28. data/lib/mtk/groups/pitch_class_set.rb +163 -0
  29. data/lib/mtk/{helpers → groups}/pitch_collection.rb +1 -1
  30. data/lib/mtk/{midi → io}/dls_synth_device.rb +3 -1
  31. data/lib/mtk/{midi → io}/dls_synth_output.rb +10 -10
  32. data/lib/mtk/{midi → io}/jsound_input.rb +2 -2
  33. data/lib/mtk/{midi → io}/jsound_output.rb +9 -9
  34. data/lib/mtk/{midi/file.rb → io/midi_file.rb} +13 -13
  35. data/lib/mtk/{midi/input.rb → io/midi_input.rb} +4 -4
  36. data/lib/mtk/{midi/output.rb → io/midi_output.rb} +8 -8
  37. data/lib/mtk/{helpers/lilypond.rb → io/notation.rb} +5 -5
  38. data/lib/mtk/{midi → io}/unimidi_input.rb +2 -2
  39. data/lib/mtk/{midi → io}/unimidi_output.rb +14 -9
  40. data/lib/mtk/{constants → lang}/durations.rb +11 -11
  41. data/lib/mtk/{constants → lang}/intensities.rb +11 -11
  42. data/lib/mtk/{constants → lang}/intervals.rb +17 -17
  43. data/lib/mtk/lang/mtk_grammar.citrus +9 -9
  44. data/lib/mtk/{constants → lang}/pitch_classes.rb +5 -5
  45. data/lib/mtk/{constants → lang}/pitches.rb +7 -7
  46. data/lib/mtk/{helpers → lang}/pseudo_constants.rb +1 -1
  47. data/lib/mtk/{variable.rb → lang/variable.rb} +1 -1
  48. data/lib/mtk/numeric_extensions.rb +40 -47
  49. data/lib/mtk/patterns/for_each.rb +1 -1
  50. data/lib/mtk/patterns/pattern.rb +3 -3
  51. data/lib/mtk/sequencers/event_builder.rb +16 -15
  52. data/lib/mtk/sequencers/legato_sequencer.rb +1 -1
  53. data/lib/mtk/sequencers/rhythmic_sequencer.rb +1 -1
  54. data/lib/mtk/sequencers/sequencer.rb +8 -8
  55. data/lib/mtk/sequencers/step_sequencer.rb +2 -2
  56. data/lib/mtk.rb +33 -39
  57. data/spec/mtk/{duration_spec.rb → core/duration_spec.rb} +3 -3
  58. data/spec/mtk/{intensity_spec.rb → core/intensity_spec.rb} +3 -3
  59. data/spec/mtk/{interval_spec.rb → core/interval_spec.rb} +1 -1
  60. data/spec/mtk/{pitch_class_spec.rb → core/pitch_class_spec.rb} +1 -1
  61. data/spec/mtk/{pitch_spec.rb → core/pitch_spec.rb} +8 -8
  62. data/spec/mtk/events/event_spec.rb +4 -4
  63. data/spec/mtk/events/note_spec.rb +8 -8
  64. data/spec/mtk/{timeline_spec.rb → events/timeline_spec.rb} +47 -47
  65. data/spec/mtk/{chord_spec.rb → groups/chord_spec.rb} +18 -16
  66. data/spec/mtk/{helpers → groups}/collection_spec.rb +3 -3
  67. data/spec/mtk/{melody_spec.rb → groups/melody_spec.rb} +36 -34
  68. data/spec/mtk/{pitch_class_set_spec.rb → groups/pitch_class_set_spec.rb} +57 -55
  69. data/spec/mtk/{midi/file_spec.rb → io/midi_file_spec.rb} +17 -17
  70. data/spec/mtk/{midi/output_spec.rb → io/midi_output_spec.rb} +6 -6
  71. data/spec/mtk/{constants → lang}/durations_spec.rb +1 -1
  72. data/spec/mtk/{constants → lang}/intensities_spec.rb +1 -1
  73. data/spec/mtk/{constants → lang}/intervals_spec.rb +1 -1
  74. data/spec/mtk/lang/parser_spec.rb +12 -6
  75. data/spec/mtk/{constants → lang}/pitch_classes_spec.rb +1 -1
  76. data/spec/mtk/{constants → lang}/pitches_spec.rb +1 -1
  77. data/spec/mtk/{helpers → lang}/pseudo_constants_spec.rb +2 -2
  78. data/spec/mtk/{variable_spec.rb → lang/variable_spec.rb} +4 -4
  79. data/spec/mtk/numeric_extensions_spec.rb +35 -55
  80. data/spec/mtk/patterns/for_each_spec.rb +1 -1
  81. data/spec/mtk/patterns/sequence_spec.rb +1 -1
  82. data/spec/mtk/sequencers/legato_sequencer_spec.rb +2 -2
  83. data/spec/mtk/sequencers/rhythmic_sequencer_spec.rb +4 -4
  84. data/spec/mtk/sequencers/step_sequencer_spec.rb +5 -5
  85. data/spec/spec_helper.rb +7 -6
  86. metadata +75 -61
  87. data/ext/mkrf_conf.rb +0 -25
  88. data/lib/mtk/chord.rb +0 -55
  89. data/lib/mtk/duration.rb +0 -211
  90. data/lib/mtk/helpers/convert.rb +0 -36
  91. data/lib/mtk/helpers/output_selector.rb +0 -67
  92. data/lib/mtk/intensity.rb +0 -156
  93. data/lib/mtk/interval.rb +0 -155
  94. data/lib/mtk/melody.rb +0 -94
  95. data/lib/mtk/pitch.rb +0 -152
  96. data/lib/mtk/pitch_class.rb +0 -192
  97. data/lib/mtk/pitch_class_set.rb +0 -161
  98. data/lib/mtk/timeline.rb +0 -230
  99. data/spec/mtk/midi/jsound_input_spec.rb +0 -11
  100. data/spec/mtk/midi/jsound_output_spec.rb +0 -11
  101. data/spec/mtk/midi/unimidi_input_spec.rb +0 -11
  102. data/spec/mtk/midi/unimidi_output_spec.rb +0 -11
@@ -1,24 +1,24 @@
1
1
  module MTK
2
2
  module Sequencers
3
3
 
4
- # A Sequencer produces {Timeline}s from a collection of {Patterns::Pattern}s.
4
+ # A Sequencer produces {Events::Timeline}s from a collection of {Patterns::Pattern}s.
5
5
  #
6
6
  # @abstract Subclass and override {#advance} to implement a Sequencer.
7
7
  #
8
8
  class Sequencer
9
9
 
10
- # The maximum number of [time,event_list] entries that will be generated for the {Timeline}.
10
+ # The maximum number of [time,event_list] entries that will be generated for the {Events::Timeline}.
11
11
  # nil means no maximum (be careful of infinite loops!)
12
12
  attr_accessor :max_steps
13
13
 
14
- # The maximum time (key) that will be generated for the {Timeline}.
14
+ # The maximum time (key) that will be generated for the {Events::Timeline}.
15
15
  # nil means no maximum (be careful of infinite loops!)
16
16
  attr_accessor :max_time
17
17
 
18
18
  # Used by {#to_timeline} to builds event lists from the results of {Patterns::Pattern#next} for the {Patterns::Pattern}s in this Sequencer.
19
19
  attr_reader :event_builder
20
20
 
21
- # The current time offset for the sequencer. Used for the {Timeline} times.
21
+ # The current time offset for the sequencer. Used for the {Events::Timeline} times.
22
22
  attr_reader :time
23
23
 
24
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.
@@ -26,7 +26,7 @@ module MTK
26
26
 
27
27
  attr_reader :patterns
28
28
 
29
- # @param patterns [Array] the list of patterns to be sequenced into a {Timeline}
29
+ # @param patterns [Array] the list of patterns to be sequenced into a {Events::Timeline}
30
30
  # @param options [Hash] the options to create a message with.
31
31
  # @option options [String] :max_steps set {#max_steps}
32
32
  # @option options [String] :max_time set {#max_time}
@@ -45,10 +45,10 @@ module MTK
45
45
  end
46
46
 
47
47
 
48
- # Produce a {Timeline} from the {Patterns::Pattern}s in this Sequencer.
48
+ # Produce a {Events::Timeline} from the {Patterns::Pattern}s in this Sequencer.
49
49
  def to_timeline
50
50
  rewind
51
- timeline = Timeline.new
51
+ timeline = MTK::Events::Timeline.new
52
52
  loop do
53
53
  events = self.next
54
54
  if events
@@ -89,7 +89,7 @@ module MTK
89
89
  ########################
90
90
  protected
91
91
 
92
- # Advance @time to the next time for the {Timeline} being produced by {#to_timeline}
92
+ # Advance @time to the next time for the {Events::Timeline} being produced by {#to_timeline}
93
93
  def advance
94
94
  @time += 1 # default behavior simply advances one beat at a time
95
95
  end
@@ -1,10 +1,10 @@
1
1
  module MTK
2
2
  module Sequencers
3
3
 
4
- # A Sequencer which has a constant {#step_size} time between {Timeline} entries.
4
+ # A Sequencer which has a constant {#step_size} time between {Events::Timeline} entries.
5
5
  class StepSequencer < Sequencer
6
6
 
7
- # The time between entries in the {Timeline}.
7
+ # The time between entries in the {Events::Timeline}.
8
8
  attr_accessor :step_size
9
9
 
10
10
  def initialize(patterns, options={})
data/lib/mtk.rb CHANGED
@@ -3,65 +3,61 @@
3
3
  # The top level module for this library
4
4
  module MTK
5
5
 
6
- # Constants for modeling frequency, intensity, and duration.
7
- module Constants
6
+ # Core data types
7
+ module Core
8
8
  end
9
9
 
10
- # Internal helper classes used to avoid duplicating code in this library.
11
- module Helpers
12
- end
13
-
14
- # Musical events, such as {Events::Note}s and {Events::Parameter} changes, that are arranged in time via a {Timeline}.
10
+ # Musical events, such as {MTK::Events::Note}s and {MTK::Events::Parameter} changes, that are arranged in time via a {MTK::Events::Timeline}.
15
11
  module Events
16
12
  end
17
13
 
18
- # Classes that emit elements one at a time. Used by {MTK::Sequencers::Sequencer}s to construct {Timeline}s.
19
- module Patterns
14
+ # Collections of {MTK::Core} objects
15
+ module Groups
20
16
  end
21
17
 
22
- # Classes that assemble {Patterns::Pattern}s into {Timeline}s.
23
- module Sequencers
18
+ # Optional classes for MIDI {MTK::IO::File} and realtime MIDI {MTK::IO::Input} and {MTK::IO::Output}.
19
+ module IO
24
20
  end
25
21
 
26
22
  # Optional classes for the "MTK language", which let's you compose music via MTK without writing any Ruby code
27
23
  module Lang
28
24
  end
29
25
 
30
- # Optional classes for MIDI input and {Output}.
31
- module MIDI
26
+ # Classes that emit elements one at a time. Used by {MTK::Sequencers::Sequencer}s to construct {MTK::Events::Timeline}s.
27
+ module Patterns
32
28
  end
33
29
 
34
- end
35
-
36
- require 'mtk/pitch_class'
37
- require 'mtk/pitch'
38
- require 'mtk/duration'
39
- require 'mtk/intensity'
40
-
41
- require 'mtk/interval'
30
+ # Classes that assemble {MTK::Patterns::Pattern}s into {MTK::Events::Timeline}s.
31
+ module Sequencers
32
+ end
42
33
 
43
- require 'mtk/variable'
34
+ end
44
35
 
45
- require 'mtk/helpers/collection'
46
- require 'mtk/helpers/pitch_collection'
47
- require 'mtk/helpers/pseudo_constants'
48
- require 'mtk/helpers/convert'
36
+ require 'mtk/core/pitch_class'
37
+ require 'mtk/core/pitch'
38
+ require 'mtk/core/duration'
39
+ require 'mtk/core/intensity'
40
+ require 'mtk/core/interval'
41
+
42
+ require 'mtk/lang/pseudo_constants'
43
+ require 'mtk/lang/pitch_classes'
44
+ require 'mtk/lang/pitches'
45
+ require 'mtk/lang/intervals'
46
+ require 'mtk/lang/intensities'
47
+ require 'mtk/lang/durations'
48
+ require 'mtk/lang/variable'
49
+ require 'mtk/lang/parser'
49
50
 
50
- require 'mtk/pitch_class_set'
51
- require 'mtk/melody'
52
- require 'mtk/chord'
51
+ require 'mtk/groups/collection'
52
+ require 'mtk/groups/pitch_collection'
53
+ require 'mtk/groups/pitch_class_set'
54
+ require 'mtk/groups/melody'
55
+ require 'mtk/groups/chord'
53
56
 
54
57
  require 'mtk/events/event'
55
58
  require 'mtk/events/note'
56
59
  require 'mtk/events/parameter'
57
-
58
- require 'mtk/timeline'
59
-
60
- require 'mtk/constants/pitch_classes'
61
- require 'mtk/constants/pitches'
62
- require 'mtk/constants/intervals'
63
- require 'mtk/constants/intensities'
64
- require 'mtk/constants/durations'
60
+ require 'mtk/events/timeline'
65
61
 
66
62
  require 'mtk/patterns/pattern'
67
63
  require 'mtk/patterns/sequence'
@@ -78,5 +74,3 @@ require 'mtk/sequencers/sequencer'
78
74
  require 'mtk/sequencers/step_sequencer'
79
75
  require 'mtk/sequencers/rhythmic_sequencer'
80
76
  require 'mtk/sequencers/legato_sequencer'
81
-
82
- require 'mtk/lang/parser'
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe MTK::Duration do
3
+ describe MTK::Core::Duration do
4
4
 
5
5
  let(:one_beat) { Duration[1] }
6
6
  let(:two_beats) { Duration[2] }
@@ -230,10 +230,10 @@ describe MTK::Duration do
230
230
  end
231
231
 
232
232
  describe '#inspect' do
233
- it 'is "#<MTK::Duration:{object_id} @value={value}>"' do
233
+ it 'is "#<MTK::Core::Duration:{object_id} @value={value}>"' do
234
234
  for value in [0, 60, 60.5, 127]
235
235
  duration = Duration.new(value)
236
- duration.inspect.should == "#<MTK::Duration:#{duration.object_id} @value=#{value}>"
236
+ duration.inspect.should == "#<MTK::Core::Duration:#{duration.object_id} @value=#{value}>"
237
237
  end
238
238
  end
239
239
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe MTK::Intensity do
3
+ describe MTK::Core::Intensity do
4
4
 
5
5
  let(:half_intensity) { Intensity[0.5] }
6
6
 
@@ -147,10 +147,10 @@ describe MTK::Intensity do
147
147
  end
148
148
 
149
149
  describe '#inspect' do
150
- it 'is "#<MTK::Intensity:{object_id} @value={value}>"' do
150
+ it 'is "#<MTK::Core::Intensity:{object_id} @value={value}>"' do
151
151
  for value in [0, 60, 60.5, 127]
152
152
  intensity = Intensity.new(value)
153
- intensity.inspect.should == "#<MTK::Intensity:#{intensity.object_id} @value=#{value}>"
153
+ intensity.inspect.should == "#<MTK::Core::Intensity:#{intensity.object_id} @value=#{value}>"
154
154
  end
155
155
  end
156
156
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe MTK::Interval do
3
+ describe MTK::Core::Interval do
4
4
 
5
5
  let(:minor_second) { Interval[1] }
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe MTK::PitchClass do
3
+ describe MTK::Core::PitchClass do
4
4
 
5
5
  let(:enharmonic_spellings_grouped_by_value) {
6
6
  # not sure how to test this without re-coding these names here
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe MTK::Pitch do
3
+ describe MTK::Core::Pitch do
4
4
 
5
5
  let(:middle_c) { Pitch.new(C, 4) }
6
6
  let(:lowest) { Pitch.new(C, -1) }
@@ -16,7 +16,7 @@ describe MTK::Pitch do
16
16
  Pitch.new(C,4).should_not be_equal Pitch[C,4]
17
17
  end
18
18
 
19
- it "can handle any type for the first argument that's supported by MTK::PitchClass()" do
19
+ it "can handle any type for the first argument that's supported by MTK::Core::PitchClass()" do
20
20
  Pitch['C',4].should == Pitch[0, 4]
21
21
  end
22
22
  end
@@ -83,9 +83,9 @@ describe MTK::Pitch do
83
83
  end
84
84
  end
85
85
 
86
- describe ".from_hash" do
86
+ describe ".from_h" do
87
87
  it "constructs a Pitch from a hash of pitch attributes" do
88
- Pitch.from_hash({:pitch_class => C, :octave => 4, :offset => 0.5}).should == middle_c_and_50_cents
88
+ Pitch.from_h({:pitch_class => C, :octave => 4, :offset => 0.5}).should == middle_c_and_50_cents
89
89
  end
90
90
  end
91
91
 
@@ -105,9 +105,9 @@ describe MTK::Pitch do
105
105
  end
106
106
  end
107
107
 
108
- describe "#to_hash" do
108
+ describe "#to_h" do
109
109
  it "converts to a Hash" do
110
- middle_c_and_50_cents.to_hash.should == {:pitch_class => C, :octave => 4, :offset => 0.5}
110
+ middle_c_and_50_cents.to_h.should == {:pitch_class => C, :octave => 4, :offset => 0.5}
111
111
  end
112
112
  end
113
113
 
@@ -142,10 +142,10 @@ describe MTK::Pitch do
142
142
  end
143
143
 
144
144
  describe '#inspect' do
145
- it 'is "#<MTK::Pitch:{object_id} @value={value}>"' do
145
+ it 'is "#<MTK::Core::Pitch:{object_id} @value={value}>"' do
146
146
  for value in [0, 60, 60.5, 127]
147
147
  pitch = Pitch.from_f(value)
148
- pitch.inspect.should == "#<MTK::Pitch:#{pitch.object_id} @value=#{value}>"
148
+ pitch.inspect.should == "#<MTK::Core::Pitch:#{pitch.object_id} @value=#{value}>"
149
149
  end
150
150
  end
151
151
  end
@@ -166,15 +166,15 @@ describe MTK::Events::Event do
166
166
  end
167
167
  end
168
168
 
169
- describe "from_hash" do
169
+ describe "from_h" do
170
170
  it "constructs an Event using a hash" do
171
- EVENT.from_hash(hash).should == event
171
+ EVENT.from_h(hash).should == event
172
172
  end
173
173
  end
174
174
 
175
- describe "#to_hash" do
175
+ describe "#to_h" do
176
176
  it "is a hash containing all the attributes of the Event" do
177
- event.to_hash.should == hash
177
+ event.to_h.should == hash
178
178
  end
179
179
  end
180
180
 
@@ -52,9 +52,9 @@ describe MTK::Events::Note do
52
52
  end
53
53
  end
54
54
 
55
- describe ".from_hash" do
55
+ describe ".from_h" do
56
56
  it "constructs a Note using a hash" do
57
- NOTE.from_hash({ :pitch => pitch, :intensity => intensity, :duration => duration }).should == note
57
+ NOTE.from_h({ :pitch => pitch, :intensity => intensity, :duration => duration }).should == note
58
58
  end
59
59
  end
60
60
 
@@ -64,9 +64,9 @@ describe MTK::Events::Note do
64
64
  end
65
65
  end
66
66
 
67
- describe "#to_hash" do
67
+ describe "#to_h" do
68
68
  it "is a hash containing all the attributes of the Note" do
69
- hash = note.to_hash
69
+ hash = note.to_h
70
70
  # hash includes some extra "baggage" for compatibility with AbstractEvent,
71
71
  # so we'll just check the fields we care about:
72
72
  hash[:pitch].should == pitch
@@ -125,8 +125,8 @@ describe MTK::Events::Note do
125
125
 
126
126
  describe "#inspect" do
127
127
  it 'is "#<MTK::Events::Note:{object_id} @pitch={pitch.inspect}, @duration={duration.inspect}, @intensity={intensity.inspect}>"' do
128
- duration = MTK::Duration(1/8.0)
129
- intensity = MTK::Intensity(1/8.0)
128
+ duration = MTK.Duration(1/8.0)
129
+ intensity = MTK.Intensity(1/8.0)
130
130
  note = NOTE.new(C4, duration, intensity)
131
131
  note.inspect.should == "#<MTK::Events::Note:#{note.object_id} @pitch=#{C4.inspect}, @duration=#{duration.inspect}, @intensity=#{intensity.inspect}>"
132
132
  end
@@ -161,11 +161,11 @@ describe MTK do
161
161
  end
162
162
 
163
163
  it "fills in a missing duration type from an number" do
164
- Note(C4,mf,5.25).should == NOTE.new(C4,MTK::Duration(5.25),mf)
164
+ Note(C4,mf,5.25).should == NOTE.new(C4,MTK.Duration(5.25),mf)
165
165
  end
166
166
 
167
167
  it '' do
168
- Note(MTK::Constants::Pitches::C4, MTK::Constants::Intensities::o, 5.25).should == Note(C4, 5.25, 0.75)
168
+ Note(MTK::Lang::Pitches::C4, MTK::Lang::Intensities::o, 5.25).should == Note(C4, 5.25, 0.75)
169
169
  end
170
170
 
171
171
  end
@@ -1,15 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe MTK::Timeline do
3
+ describe MTK::Events::Timeline do
4
4
 
5
5
  let(:note1) { Note(C4, p, 1) }
6
6
  let(:note2) { Note(G4, o, 2) }
7
7
  let(:timeline_raw_data) { { 0.0 => note1, 1.0 => [note1, note2] } }
8
8
  let(:timeline_hash) { { 0.0 => [note1], 1.0 => [note1, note2] } }
9
- let(:timeline) { Timeline.from_hash(timeline_raw_data) }
9
+ let(:timeline) { MTK::Events::Timeline.from_h(timeline_raw_data) }
10
10
 
11
11
  let(:unquantized_data) { { 0.0 => [note1], 0.7 => [note1], 1.1 => [note2], 1.24 => [note1], 1.25 => [note1] } }
12
- let(:unquantized_timeline) { Timeline.from_hash(unquantized_data) }
12
+ let(:unquantized_timeline) { MTK::Events::Timeline.from_h(unquantized_data) }
13
13
  let(:quantization_interval) { 0.5 }
14
14
  let(:quantized_data) { { 0.0 => [note1], 0.5 => [note1], 1.0 => [note2, note1], 1.5 => [note1] } }
15
15
 
@@ -18,26 +18,26 @@ describe MTK::Timeline do
18
18
  let(:shift_amount) { 5 }
19
19
 
20
20
  it "is Enumerable" do
21
- Timeline.new.should be_a Enumerable
21
+ MTK::Events::Timeline.new.should be_a Enumerable
22
22
  end
23
23
 
24
24
  it "wraps lone values in arrays" do
25
- Timeline.from_hash(timeline_raw_data).should == Timeline.from_hash(timeline_hash)
25
+ MTK::Events::Timeline.from_h(timeline_raw_data).should == MTK::Events::Timeline.from_h(timeline_hash)
26
26
  end
27
27
 
28
- describe "from_hash" do
28
+ describe "from_h" do
29
29
  it "creates an empty timeline when the hash is empty" do
30
- Timeline.from_hash({}).should be_empty
30
+ MTK::Events::Timeline.from_h({}).should be_empty
31
31
  end
32
32
 
33
33
  it "builds a Timeline from a map of times to single events" do
34
- t = Timeline.from_hash({ 0 => note1, 1 => note2 })
34
+ t = MTK::Events::Timeline.from_h({ 0 => note1, 1 => note2 })
35
35
  t[0].should == [note1]
36
36
  t[1].should == [note2]
37
37
  end
38
38
 
39
39
  it "builds a Timeline from a map of times to event lists" do
40
- t = Timeline.from_hash({ 0 => [note1, note2], 1 => [note2] })
40
+ t = MTK::Events::Timeline.from_h({ 0 => [note1, note2], 1 => [note2] })
41
41
  t[0].should == [note1, note2]
42
42
  t[1].should == [note2]
43
43
  end
@@ -45,13 +45,13 @@ describe MTK::Timeline do
45
45
 
46
46
  describe "from_a" do
47
47
  it "creates a timeline from an Enumerable" do
48
- Timeline.from_a(timeline_hash.to_a).should == timeline
48
+ MTK::Events::Timeline.from_a(timeline_hash.to_a).should == timeline
49
49
  end
50
50
  end
51
51
 
52
- describe "#to_hash" do
52
+ describe "#to_h" do
53
53
  it "returns the underlying Hash" do
54
- timeline.to_hash.should == timeline_hash
54
+ timeline.to_h.should == timeline_hash
55
55
  end
56
56
  end
57
57
 
@@ -63,13 +63,13 @@ describe MTK::Timeline do
63
63
 
64
64
  describe "#merge" do
65
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 }) )
66
+ timeline.merge({ 3 => note2 }).should == MTK::Events::Timeline.from_h( timeline_raw_data.merge({ 3 => note2 }) )
67
67
  end
68
68
  end
69
69
 
70
70
  describe "#empty?" do
71
71
  it "is true when the timeilne has no events" do
72
- Timeline.new.empty?.should be_true
72
+ MTK::Events::Timeline.new.empty?.should be_true
73
73
  end
74
74
  end
75
75
 
@@ -109,7 +109,7 @@ describe MTK::Timeline do
109
109
  end
110
110
 
111
111
  it "coerces the argument to floating point for consistent lookup behavior" do
112
- timeline = Timeline.new
112
+ timeline = MTK::Events::Timeline.new
113
113
  timeline[nil] = note1
114
114
  timeline[1] = note1
115
115
  timeline[Rational(3,2)] = note1
@@ -136,7 +136,7 @@ describe MTK::Timeline do
136
136
  end
137
137
 
138
138
  it "coerces the argument to floating point for consistent lookup behavior" do
139
- timeline = Timeline.new
139
+ timeline = MTK::Events::Timeline.new
140
140
  timeline.add(nil, note1)
141
141
  timeline.add(1, note1)
142
142
  timeline.add(Rational(3,2), note1)
@@ -174,14 +174,14 @@ describe MTK::Timeline do
174
174
  describe "length" do
175
175
  it "is the lastest time + the longest duration of events at that time" do
176
176
  len = timeline.length
177
- len.should be_a ::MTK::Duration
177
+ len.should be_a ::MTK::Core::Duration
178
178
  len.should == ::MTK.Duration(3)
179
179
  end
180
180
  end
181
181
 
182
182
  describe "empty?" do
183
183
  it "is true when there are no events in the timeline" do
184
- Timeline.new.empty?.should be_true
184
+ MTK::Events::Timeline.new.empty?.should be_true
185
185
  end
186
186
 
187
187
  it "is false where there are events in the timeline" do
@@ -191,10 +191,10 @@ describe MTK::Timeline do
191
191
 
192
192
  describe "#==" do
193
193
  it "is true when the underlying Hashes are equal" do
194
- timeline.should == Timeline.from_hash(timeline_hash)
194
+ timeline.should == MTK::Events::Timeline.from_h(timeline_hash)
195
195
  end
196
196
  it "is false when the underlying Hashes are not equal" do
197
- timeline.should_not == Timeline.from_hash( {0 => [note2], 1 => [note1, note2]} )
197
+ timeline.should_not == MTK::Events::Timeline.from_h( {0 => [note2], 1 => [note1, note2]} )
198
198
  end
199
199
  it "allows for direct comparison to hashes" do
200
200
  timeline.should == timeline_hash
@@ -216,13 +216,13 @@ describe MTK::Timeline do
216
216
  end
217
217
 
218
218
  describe "#map" do
219
- it "returns a new Timeline where each [time,event] pair is replaced by the result of block" do
219
+ it "returns a new MTK::Events::Timeline where each [time,event] pair is replaced by the result of block" do
220
220
  mapped = timeline.map{|time,events| [time+1, events.map{|e| e.transpose(time+2) }] }
221
221
  mapped.should == { 1.0 => [note1.transpose(2)], 2.0 => [note1.transpose(3), note2.transpose(3)] }
222
222
  end
223
223
 
224
224
  it "handle events from different times being mapped to the same time" do
225
- timeline = MTK::Timeline.from_hash({ 0.0 => [note1], 1.0 => [note1], 2.0 => [note2] })
225
+ timeline = MTK::Events::Timeline.from_h({ 0.0 => [note1], 1.0 => [note1], 2.0 => [note2] })
226
226
  mapped = timeline.map do |time,events|
227
227
  if events == [note1]
228
228
  [1.0, events]
@@ -233,33 +233,33 @@ describe MTK::Timeline do
233
233
  mapped.should == { 1.0 => [note1,note1], 2.0 => [note2] }
234
234
  end
235
235
 
236
- it "does not modify this Timeline" do
236
+ it "does not modify this MTK::Events::Timeline" do
237
237
  timeline.map{|t,e| [0,nil] }
238
238
  timeline.should == timeline_hash
239
239
  end
240
240
  end
241
241
 
242
242
  describe "#map!" do
243
- it "maps the Timeline in place" do
243
+ it "maps the MTK::Events::Timeline in place" do
244
244
  timeline.map! {|time,events| [time+1, events.map{|e| e.transpose(time+2) }] }
245
245
  timeline.should == { 1.0 => [note1.transpose(2)], 2.0 => [note1.transpose(3), note2.transpose(3)] }
246
246
  end
247
247
  end
248
248
 
249
249
  describe "#map_events" do
250
- it "maps the Timeline in place" do
250
+ it "maps the MTK::Events::Timeline in place" do
251
251
  mapped = timeline.map_events {|event| event.transpose(1) }
252
252
  mapped.should == { 0.0 => [note1.transpose(1)], 1.0 => [note1.transpose(1), note2.transpose(1)] }
253
253
  end
254
254
 
255
- it "does not modify this Timeline" do
255
+ it "does not modify this MTK::Events::Timeline" do
256
256
  timeline.map_events {|event| event.transpose(1) }
257
257
  timeline.should == timeline_hash
258
258
  end
259
259
  end
260
260
 
261
261
  describe "#map_events!" do
262
- it "maps the Timeline in place" do
262
+ it "maps the MTK::Events::Timeline in place" do
263
263
  timeline.map_events! {|event| event.transpose(1.0) }
264
264
  timeline.should == { 0.0 => [note1.transpose(1)], 1.0 => [note1.transpose(1), note2.transpose(1)] }
265
265
  end
@@ -278,7 +278,7 @@ describe MTK::Timeline do
278
278
  it "maps all times to the nearest multiple of the given interval" do
279
279
  unquantized_timeline.quantize(quantization_interval).should == quantized_data
280
280
  end
281
- it "returns a new Timeline and does not modify the original" do
281
+ it "returns a new MTK::Events::Timeline and does not modify the original" do
282
282
  unquantized_timeline.quantize(quantization_interval)
283
283
  unquantized_timeline.should == unquantized_data
284
284
  end
@@ -289,7 +289,7 @@ describe MTK::Timeline do
289
289
  unquantized_timeline.quantize!(quantization_interval).should == quantized_data
290
290
  end
291
291
 
292
- it "modifies the Timeline in place" do
292
+ it "modifies the MTK::Events::Timeline in place" do
293
293
  unquantized_timeline.quantize!(quantization_interval)
294
294
  unquantized_timeline.should == quantized_data
295
295
  end
@@ -308,7 +308,7 @@ describe MTK::Timeline do
308
308
  timeline.shift(shift_amount).should be_a timeline.class
309
309
  end
310
310
 
311
- it "returns a new Timeline and does not modify the original" do
311
+ it "returns a new MTK::Events::Timeline and does not modify the original" do
312
312
  timeline.shift(shift_amount).should_not equal timeline
313
313
  end
314
314
  end
@@ -329,23 +329,23 @@ describe MTK::Timeline do
329
329
 
330
330
  describe "#shift_to" do
331
331
  it "shifts so the start is at the given time" do
332
- Timeline.from_hash(shifted_data).shift_to(0).should == timeline
333
- Timeline.from_hash(reverse_shifted_data).shift_to(0).should == timeline
332
+ MTK::Events::Timeline.from_h(shifted_data).shift_to(0).should == timeline
333
+ MTK::Events::Timeline.from_h(reverse_shifted_data).shift_to(0).should == timeline
334
334
  end
335
335
 
336
336
  it "returns an instance of the same type" do
337
337
  timeline.shift_to(shift_amount).should be_a timeline.class
338
338
  end
339
339
 
340
- it "returns a new Timeline and does not modify the original" do
340
+ it "returns a new MTK::Events::Timeline and does not modify the original" do
341
341
  timeline.shift_to(shift_amount).should_not equal timeline
342
342
  end
343
343
  end
344
344
 
345
345
  describe "#shift_to!" do
346
346
  it "shifts so the start is at the given time" do
347
- Timeline.from_hash(shifted_data).shift_to!(0).should == timeline
348
- Timeline.from_hash(reverse_shifted_data).shift_to!(0).should == timeline
347
+ MTK::Events::Timeline.from_h(shifted_data).shift_to!(0).should == timeline
348
+ MTK::Events::Timeline.from_h(reverse_shifted_data).shift_to!(0).should == timeline
349
349
  end
350
350
 
351
351
  it "modifies the timeline in place" do
@@ -355,28 +355,28 @@ describe MTK::Timeline do
355
355
 
356
356
  describe "#flatten" do
357
357
  it "flattens nested timelines so that all nested subtimes are converted to absolute times in a single timeline" do
358
- timeline[10] = Timeline.from_hash({ 0 => note2, 1 => note1 })
358
+ timeline[10] = MTK::Events::Timeline.from_h({ 0 => note2, 1 => note1 })
359
359
  timeline.flatten.should == timeline_hash.merge({ 10.0 => [note2], 11.0 => [note1] })
360
360
  end
361
361
 
362
362
  it "handles nested timelines which have nested timelines inside of them" do
363
- nested = Timeline.from_hash({ 0 => note1 })
364
- timeline[10] = Timeline.from_hash({ 100 => nested })
363
+ nested = MTK::Events::Timeline.from_h({ 0 => note1 })
364
+ timeline[10] = MTK::Events::Timeline.from_h({ 100 => nested })
365
365
  timeline.flatten.should == timeline_hash.merge({ 110.0 => [note1] })
366
366
  end
367
367
 
368
368
  it "handles multiple nested timeslines at the same time point" do
369
- timeline[10] = [Timeline.from_hash({ 0 => note2, 1 => note1 }), Timeline.from_hash({ 2 => note1, 3 => note2 })]
369
+ timeline[10] = [ MTK::Events::Timeline.from_h({ 0 => note2, 1 => note1 }), MTK::Events::Timeline.from_h({ 2 => note1, 3 => note2 })]
370
370
  timeline.flatten.should == timeline_hash.merge({ 10.0 => [note2], 11.0 => [note1], 12.0 => [note1], 13.0 => [note2] })
371
371
  end
372
372
 
373
- it "returns a new Timeline" do
373
+ it "returns a new MTK::Events::Timeline" do
374
374
  timeline.flatten.should_not equal(timeline)
375
375
  end
376
376
  end
377
377
 
378
378
  describe "#clone" do
379
- it "creates an equal Timeline" do
379
+ it "creates an equal MTK::Events::Timeline" do
380
380
  timeline.clone.should == timeline
381
381
  end
382
382
 
@@ -387,17 +387,17 @@ describe MTK::Timeline do
387
387
 
388
388
  describe ".quantize_time" do
389
389
  it "takes a time and an interval, and returns the nearest multiple of the interval to the time" do
390
- Timeline.quantize_time(23,10).should == 20
391
- Timeline.quantize_time(27,10).should == 30
392
- Timeline.quantize_time(30,10).should == 30
390
+ MTK::Events::Timeline.quantize_time(23,10).should == 20
391
+ MTK::Events::Timeline.quantize_time(27,10).should == 30
392
+ MTK::Events::Timeline.quantize_time(30,10).should == 30
393
393
  end
394
394
 
395
395
  it "rounds up when exactly between 2 intervals" do
396
- Timeline.quantize_time(25,10).should == 30
396
+ MTK::Events::Timeline.quantize_time(25,10).should == 30
397
397
  end
398
398
 
399
399
  it "handles fractional intervals" do
400
- Timeline.quantize_time(13,2.5).should == 12.5
400
+ MTK::Events::Timeline.quantize_time(13,2.5).should == 12.5
401
401
  end
402
402
  end
403
403
 
@@ -414,7 +414,7 @@ describe MTK::Timeline do
414
414
 
415
415
  it "pretty prints the output by aligning all '=>' arrows" do
416
416
  # alignment is only a factor when the times have different numbers of digits:
417
- timeline = Timeline.new
417
+ timeline = MTK::Events::Timeline.new
418
418
  timeline.add 0, note1
419
419
  timeline.add 10, note1
420
420
  timeline.add 1000, note1