midilib 2.0.4 → 2.0.5

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 (94) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +9 -4
  3. data/Rakefile +2 -6
  4. data/examples/from_scratch.rb +3 -5
  5. data/examples/measures_mbt.rb +4 -4
  6. data/examples/print_program_changes.rb +9 -9
  7. data/examples/reader2text.rb +188 -188
  8. data/examples/seq2text.rb +17 -17
  9. data/examples/split.rb +19 -19
  10. data/examples/strings.rb +14 -14
  11. data/examples/transpose.rb +31 -31
  12. data/html/IO.html +65 -169
  13. data/html/MIDI.html +138 -256
  14. data/html/MIDI/ActiveSense.html +89 -178
  15. data/html/MIDI/ChannelEvent.html +95 -183
  16. data/html/MIDI/ChannelPressure.html +105 -190
  17. data/html/MIDI/Clock.html +89 -178
  18. data/html/MIDI/Continue.html +89 -178
  19. data/html/MIDI/Controller.html +107 -192
  20. data/html/MIDI/Event.html +138 -222
  21. data/html/MIDI/IO.html +45 -157
  22. data/html/MIDI/IO/MIDIFile.html +596 -568
  23. data/html/MIDI/IO/SeqReader.html +272 -314
  24. data/html/MIDI/IO/SeqWriter.html +229 -305
  25. data/html/MIDI/KeySig.html +129 -211
  26. data/html/MIDI/MIDI.html +45 -154
  27. data/html/MIDI/MIDI/MIDI.html +45 -154
  28. data/html/MIDI/MIDI/MIDI/Array.html +87 -185
  29. data/html/MIDI/Marker.html +71 -170
  30. data/html/MIDI/Measure.html +95 -190
  31. data/html/MIDI/Measures.html +103 -193
  32. data/html/MIDI/MetaEvent.html +180 -253
  33. data/html/MIDI/NoteEvent.html +118 -204
  34. data/html/MIDI/NoteOff.html +95 -183
  35. data/html/MIDI/NoteOn.html +95 -183
  36. data/html/MIDI/PitchBend.html +106 -191
  37. data/html/MIDI/PolyPressure.html +106 -189
  38. data/html/MIDI/ProgramChange.html +105 -190
  39. data/html/MIDI/Realtime.html +98 -184
  40. data/html/MIDI/Sequence.html +246 -311
  41. data/html/MIDI/SongPointer.html +106 -191
  42. data/html/MIDI/SongSelect.html +105 -190
  43. data/html/MIDI/Start.html +89 -178
  44. data/html/MIDI/Stop.html +89 -178
  45. data/html/MIDI/SystemCommon.html +71 -170
  46. data/html/MIDI/SystemExclusive.html +108 -193
  47. data/html/MIDI/SystemReset.html +89 -178
  48. data/html/MIDI/Tempo.html +135 -213
  49. data/html/MIDI/TimeSig.html +135 -214
  50. data/html/MIDI/Track.html +217 -291
  51. data/html/MIDI/TuneRequest.html +98 -184
  52. data/html/MIDI/Utils.html +89 -189
  53. data/html/README_rdoc.html +237 -257
  54. data/html/TODO_rdoc.html +64 -139
  55. data/html/created.rid +14 -14
  56. data/html/css/fonts.css +167 -0
  57. data/html/{rdoc.css → css/rdoc.css} +265 -218
  58. data/html/fonts/Lato-Light.ttf +0 -0
  59. data/html/fonts/Lato-LightItalic.ttf +0 -0
  60. data/html/fonts/Lato-Regular.ttf +0 -0
  61. data/html/fonts/Lato-RegularItalic.ttf +0 -0
  62. data/html/fonts/SourceCodePro-Bold.ttf +0 -0
  63. data/html/fonts/SourceCodePro-Regular.ttf +0 -0
  64. data/html/images/add.png +0 -0
  65. data/html/images/arrow_up.png +0 -0
  66. data/html/images/delete.png +0 -0
  67. data/html/images/tag_blue.png +0 -0
  68. data/html/index.html +187 -169
  69. data/html/js/darkfish.js +41 -33
  70. data/html/js/jquery.js +4 -18
  71. data/html/js/navigation.js.gz +0 -0
  72. data/html/js/search.js +20 -5
  73. data/html/js/search_index.js +1 -1
  74. data/html/js/search_index.js.gz +0 -0
  75. data/html/js/searcher.js.gz +0 -0
  76. data/html/table_of_contents.html +1111 -498
  77. data/install.rb +43 -32
  78. data/lib/midilib/consts.rb +407 -407
  79. data/lib/midilib/event.rb +295 -294
  80. data/lib/midilib/info.rb +5 -5
  81. data/lib/midilib/io/midifile.rb +266 -267
  82. data/lib/midilib/io/seqreader.rb +106 -106
  83. data/lib/midilib/io/seqwriter.rb +59 -60
  84. data/lib/midilib/measure.rb +69 -69
  85. data/lib/midilib/sequence.rb +68 -70
  86. data/lib/midilib/track.rb +96 -102
  87. data/lib/midilib/utils.rb +15 -15
  88. data/test/event_equality.rb +50 -50
  89. data/test/test_event.rb +120 -122
  90. data/test/test_io.rb +35 -48
  91. data/test/test_sequence.rb +60 -60
  92. data/test/test_track.rb +154 -154
  93. data/test/test_varlen.rb +23 -25
  94. metadata +65 -57
@@ -2,79 +2,79 @@ require 'midilib/consts'
2
2
 
3
3
  module MIDI
4
4
 
5
- # The Measure class contains information about a measure from the sequence.
6
- # The measure data is based on the time signature information from the sequence
7
- # and is not stored in the sequence itself
8
- class Measure
9
- # The numerator (top digit) for the measure's time signature
10
- attr_reader :numerator
11
- # The denominator for the measure's time signature
12
- attr_reader :denominator
13
- # Start clock tick for the measure
14
- attr_reader :start
15
- # End clock tick for the measure (inclusive)
16
- attr_reader :end
17
- # The measure number (1-based)
18
- attr_reader :measure_number
19
- # The metronome tick for the measure
20
- attr_reader :metronome_ticks
21
-
22
- # Constructor
23
- def initialize(meas_no, start_time, duration, numer, denom, met_ticks)
24
- @measure_number = meas_no
25
- @start = start_time
26
- @end = start_time + duration - 1
27
- @numerator = numer
28
- @denominator = denom
29
- @metronome_ticks = met_ticks
30
- end
31
-
32
- # Returns a detailed string with information about the measure
33
- def to_s
34
- t = "#{@numerator}/#{2**@denominator}"
35
- m = @metronome_ticks.to_f / 24
36
- "measure #{@measure_number} #{@start}-#{@end} #{t} #{m} qs metronome"
37
- end
38
-
39
- # Returns +true+ if the event is in the measure
40
- def contains_event?(e)
41
- (e.time_from_start >= @start) && (e.time_from_start <= @end)
5
+ # The Measure class contains information about a measure from the sequence.
6
+ # The measure data is based on the time signature information from the sequence
7
+ # and is not stored in the sequence itself
8
+ class Measure
9
+ # The numerator (top digit) for the measure's time signature
10
+ attr_reader :numerator
11
+ # The denominator for the measure's time signature
12
+ attr_reader :denominator
13
+ # Start clock tick for the measure
14
+ attr_reader :start
15
+ # End clock tick for the measure (inclusive)
16
+ attr_reader :end
17
+ # The measure number (1-based)
18
+ attr_reader :measure_number
19
+ # The metronome tick for the measure
20
+ attr_reader :metronome_ticks
21
+
22
+ # Constructor
23
+ def initialize(meas_no, start_time, duration, numer, denom, met_ticks)
24
+ @measure_number = meas_no
25
+ @start = start_time
26
+ @end = start_time + duration - 1
27
+ @numerator = numer
28
+ @denominator = denom
29
+ @metronome_ticks = met_ticks
30
+ end
31
+
32
+ # Returns a detailed string with information about the measure
33
+ def to_s
34
+ t = "#{@numerator}/#{2**@denominator}"
35
+ m = @metronome_ticks.to_f / 24
36
+ "measure #{@measure_number} #{@start}-#{@end} #{t} #{m} qs metronome"
37
+ end
38
+
39
+ # Returns +true+ if the event is in the measure
40
+ def contains_event?(e)
41
+ (e.time_from_start >= @start) && (e.time_from_start <= @end)
42
+ end
42
43
  end
43
- end
44
44
 
45
- # A specialized container for MIDI::Measure objects, which can be use to map
46
- # event times to measure numbers. Please note that this object has to be remade
47
- # when events are deleted/added in the sequence.
48
- class Measures < Array
49
- # The highest event time in the sequence (at the time when the
50
- # object was created)
51
- attr_reader :max_time
52
-
53
- # The ppqd from the sequence
54
- attr_reader :ppqd
55
-
56
- # Constructor
57
- def initialize(max_time, ppqd)
45
+ # A specialized container for MIDI::Measure objects, which can be use to map
46
+ # event times to measure numbers. Please note that this object has to be remade
47
+ # when events are deleted/added in the sequence.
48
+ class Measures < Array
49
+ # The highest event time in the sequence (at the time when the
50
+ # object was created)
51
+ attr_reader :max_time
52
+
53
+ # The ppqd from the sequence
54
+ attr_reader :ppqd
55
+
56
+ # Constructor
57
+ def initialize(max_time, ppqd)
58
58
  super(0)
59
59
  @max_time = max_time
60
60
  @ppqd = ppqd
61
- end
62
-
63
- # Returns the MIDI::Measure object where the event is located.
64
- # Returns +nil+ if the event isn't found in the container (should
65
- # never happen if the MIDI::Measures object is up to date).
66
- def measure_for_event(e)
67
- detect { | m | m.contains_event?(e) }
68
- end
69
-
70
- # Returns the event's time as a formatted MBT string (Measure:Beat:Ticks)
71
- # as found in MIDI sequencers.
72
- def to_mbt(e)
73
- m = measure_for_event(e)
74
- b = (e.time_from_start.to_f - m.start.to_f) / @ppqd
75
- b *= 24 / m.metronome_ticks
76
- sprintf("%d:%02d:%03d", m.measure_number, b.to_i + 1, (b - b.to_i) * @ppqd)
77
- end
78
- end
61
+ end
62
+
63
+ # Returns the MIDI::Measure object where the event is located.
64
+ # Returns +nil+ if the event isn't found in the container (should
65
+ # never happen if the MIDI::Measures object is up to date).
66
+ def measure_for_event(e)
67
+ detect { |m| m.contains_event?(e) }
68
+ end
69
+
70
+ # Returns the event's time as a formatted MBT string (Measure:Beat:Ticks)
71
+ # as found in MIDI sequencers.
72
+ def to_mbt(e)
73
+ m = measure_for_event(e)
74
+ b = (e.time_from_start.to_f - m.start.to_f) / @ppqd
75
+ b *= 24 / m.metronome_ticks
76
+ sprintf("%d:%02d:%03d", m.measure_number, b.to_i + 1, (b - b.to_i) * @ppqd)
77
+ end
78
+ end
79
79
 
80
80
  end
@@ -4,8 +4,8 @@ require 'midilib/measure.rb'
4
4
 
5
5
  module MIDI
6
6
 
7
- # A MIDI::Sequence contains MIDI::Track objects.
8
- class Sequence
7
+ # A MIDI::Sequence contains MIDI::Track objects.
8
+ class Sequence
9
9
 
10
10
  include Enumerable
11
11
 
@@ -33,7 +33,7 @@ class Sequence
33
33
  # Pulses (i.e. clocks) Per Quarter Note resolution for the sequence
34
34
  attr_accessor :ppqn
35
35
  # The MIDI file format (0, 1, or 2)
36
- attr_accessor :format
36
+ attr_accessor :format
37
37
  attr_accessor :numer, :denom, :clocks, :qnotes
38
38
  # The class to use for reading MIDI from a stream. The default is
39
39
  # MIDI::IO::SeqReader. You can change this at any time.
@@ -43,34 +43,32 @@ class Sequence
43
43
  attr_accessor :writer_class
44
44
 
45
45
  def initialize
46
- @tracks = Array.new()
47
- @ppqn = 480
46
+ @tracks = Array.new()
47
+ @ppqn = 480
48
48
 
49
- # Time signature
50
- @numer = 4 # Numer + denom = 4/4 time default
51
- @denom = 2
52
- @clocks = 24 # Bug fix Nov 11, 2007 - this is not the same as ppqn!
53
- @qnotes = 8
49
+ # Time signature
50
+ @numer = 4 # Numer + denom = 4/4 time default
51
+ @denom = 2
52
+ @clocks = 24 # Bug fix Nov 11, 2007 - this is not the same as ppqn!
53
+ @qnotes = 8
54
54
 
55
- @reader_class = IO::SeqReader
56
- @writer_class = IO::SeqWriter
55
+ @reader_class = IO::SeqReader
56
+ @writer_class = IO::SeqWriter
57
57
  end
58
58
 
59
59
  # Sets the time signature.
60
60
  def time_signature(numer, denom, clocks, qnotes)
61
- @numer = numer
62
- @denom = denom
63
- @clocks = clocks
64
- @qnotes = qnotes
61
+ @numer = numer
62
+ @denom = denom
63
+ @clocks = clocks
64
+ @qnotes = qnotes
65
65
  end
66
66
 
67
67
  # Returns the song tempo in beats per minute.
68
68
  def beats_per_minute
69
- return DEFAULT_TEMPO if @tracks.nil? || @tracks.empty?
70
- event = @tracks.first.events.detect { | e |
71
- e.kind_of?(MIDI::Tempo)
72
- }
73
- return event ? (Tempo.mpq_to_bpm(event.tempo)) : DEFAULT_TEMPO
69
+ return DEFAULT_TEMPO if @tracks.nil? || @tracks.empty?
70
+ event = @tracks.first.events.detect { |e| e.kind_of?(MIDI::Tempo) }
71
+ return event ? (Tempo.mpq_to_bpm(event.tempo)) : DEFAULT_TEMPO
74
72
  end
75
73
  alias_method :bpm, :beats_per_minute
76
74
  alias_method :tempo, :beats_per_minute
@@ -125,74 +123,74 @@ class Sequence
125
123
  # Returns the name of the first track (track zero). If there are no
126
124
  # tracks, returns UNNAMED.
127
125
  def name
128
- return UNNAMED if @tracks.empty?
129
- return @tracks.first.name()
126
+ return UNNAMED if @tracks.empty?
127
+ return @tracks.first.name()
130
128
  end
131
129
 
132
130
  # Hands the name to the first track. Does nothing if there are no tracks.
133
131
  def name=(name)
134
- return if @tracks.empty?
135
- @tracks.first.name = name
132
+ return if @tracks.empty?
133
+ @tracks.first.name = name
136
134
  end
137
135
 
138
136
  # Reads a MIDI stream.
139
137
  def read(io, proc = nil) # :yields: track, num_tracks, index
140
- reader = @reader_class.new(self, block_given?() ? Proc.new() : proc)
141
- reader.read_from(io)
138
+ reader = @reader_class.new(self, block_given?() ? Proc.new() : proc)
139
+ reader.read_from(io)
142
140
  end
143
141
 
144
142
  # Writes to a MIDI stream.
145
143
  def write(io, proc = nil) # :yields: track, num_tracks, index
146
- writer = @writer_class.new(self, block_given?() ? Proc.new() : proc)
147
- writer.write_to(io)
144
+ writer = @writer_class.new(self, block_given?() ? Proc.new() : proc)
145
+ writer.write_to(io)
148
146
  end
149
147
 
150
148
  # Iterates over the tracks.
151
149
  def each # :yields: track
152
- @tracks.each { | track | yield track }
150
+ @tracks.each { |track| yield track }
153
151
  end
154
152
 
155
153
  # Returns a Measures object, which is an array container for all measures
156
154
  # in the sequence
157
- def get_measures
158
- # Collect time sig events and scan for last event time
159
- time_sigs = []
160
- max_pos = 0
161
- @tracks.each { |t|
162
- t.each { |e|
163
- time_sigs << e if e.kind_of?(MIDI::TimeSig)
164
- max_pos = e.time_from_start if e.time_from_start > max_pos
165
- }
166
- }
167
- time_sigs.sort { |x,y| x.time_from_start <=> y.time_from_start }
168
-
169
- # Add a "fake" time sig event at the very last position of the sequence,
170
- # just to make sure the whole sequence is calculated.
171
- t = MIDI::TimeSig.new(4, 2, 24, 8, 0)
172
- t.time_from_start = max_pos
173
- time_sigs << t
174
-
175
- # Default to 4/4
176
- measure_length = @ppqn * 4
177
- oldnumer, olddenom, oldbeats = 4, 2, 24
178
-
179
- measures = MIDI::Measures.new(max_pos, @ppqn)
180
- curr_pos = 0
181
- curr_meas_no = 1
182
- time_sigs.each { |te|
183
- meas_count = (te.time_from_start - curr_pos) / measure_length
184
- meas_count += 1 if (te.time_from_start - curr_pos) % measure_length > 0
185
- 1.upto(meas_count) { |i|
186
- measures << MIDI::Measure.new(curr_meas_no,
187
- curr_pos, measure_length, oldnumer, olddenom, oldbeats)
188
- curr_meas_no += 1
189
- curr_pos += measure_length
190
- }
191
- oldnumer, olddenom, oldbeats = te.numerator, te.denominator, te.metronome_ticks
192
- measure_length = te.measure_duration(@ppqn)
193
- }
194
- measures
155
+ def get_measures
156
+ # Collect time sig events and scan for last event time
157
+ time_sigs = []
158
+ max_pos = 0
159
+ @tracks.each do |t|
160
+ t.each do |e|
161
+ time_sigs << e if e.kind_of?(MIDI::TimeSig)
162
+ max_pos = e.time_from_start if e.time_from_start > max_pos
163
+ end
164
+ end
165
+ time_sigs.sort { |x,y| x.time_from_start <=> y.time_from_start }
166
+
167
+ # Add a "fake" time sig event at the very last position of the sequence,
168
+ # just to make sure the whole sequence is calculated.
169
+ t = MIDI::TimeSig.new(4, 2, 24, 8, 0)
170
+ t.time_from_start = max_pos
171
+ time_sigs << t
172
+
173
+ # Default to 4/4
174
+ measure_length = @ppqn * 4
175
+ oldnumer, olddenom, oldbeats = 4, 2, 24
176
+
177
+ measures = MIDI::Measures.new(max_pos, @ppqn)
178
+ curr_pos = 0
179
+ curr_meas_no = 1
180
+ time_sigs.each do |te|
181
+ meas_count = (te.time_from_start - curr_pos) / measure_length
182
+ meas_count += 1 if (te.time_from_start - curr_pos) % measure_length > 0
183
+ 1.upto(meas_count) do |i|
184
+ measures << MIDI::Measure.new(curr_meas_no, curr_pos, measure_length,
185
+ oldnumer, olddenom, oldbeats)
186
+ curr_meas_no += 1
187
+ curr_pos += measure_length
188
+ end
189
+ oldnumer, olddenom, oldbeats = te.numerator, te.denominator, te.metronome_ticks
190
+ measure_length = te.measure_duration(@ppqn)
191
+ end
192
+ measures
195
193
  end
196
-
197
- end
194
+
195
+ end
198
196
  end
@@ -2,58 +2,56 @@ require 'midilib/event'
2
2
 
3
3
  module MIDI
4
4
 
5
- # This is taken from
6
- # http://github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb
7
- # with permission from Adam Murray, who originally suggested this fix.
8
- # See http://wiki.github.com/adamjmurray/cosy/midilib-notes for details.
9
- # First we need to add some API infrastructure:
10
- class MIDI::Array < ::Array
11
- # This code borrowed from 'Moser' http://codesnippets.joyent.com/posts/show/1699
12
-
13
- # A stable sorting algorithm that maintains the relative order of equal elements
14
- def mergesort(&cmp)
15
- if cmp == nil
16
- cmp = lambda { |a, b| a <=> b }
17
- end
18
- if size <= 1
19
- self.dup
20
- else
21
- halves = split.map{ |half|
22
- half.mergesort(&cmp)
23
- }
24
- merge(*halves, &cmp)
5
+ # This is taken from
6
+ # http://github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb
7
+ # with permission from Adam Murray, who originally suggested this fix.
8
+ # See http://wiki.github.com/adamjmurray/cosy/midilib-notes for details.
9
+ # First we need to add some API infrastructure:
10
+ class MIDI::Array < ::Array
11
+ # This code borrowed from 'Moser' http://codesnippets.joyent.com/posts/show/1699
12
+
13
+ # A stable sorting algorithm that maintains the relative order of equal elements
14
+ def mergesort(&cmp)
15
+ if cmp == nil
16
+ cmp = lambda { |a, b| a <=> b }
17
+ end
18
+ if size <= 1
19
+ self.dup
20
+ else
21
+ halves = split.map { |half| half.mergesort(&cmp) }
22
+ merge(*halves, &cmp)
23
+ end
25
24
  end
26
- end
27
25
 
28
- protected
29
- def split
30
- n = (length / 2).floor - 1
31
- [self[0..n], self[n+1..-1]]
32
- end
26
+ protected
27
+ def split
28
+ n = (length / 2).floor - 1
29
+ [self[0..n], self[n+1..-1]]
30
+ end
33
31
 
34
- def merge(first, second, &predicate)
35
- result = []
36
- until first.empty? || second.empty?
37
- if predicate.call(first.first, second.first) <= 0
38
- result << first.shift
39
- else
40
- result << second.shift
32
+ def merge(first, second, &predicate)
33
+ result = []
34
+ until first.empty? || second.empty?
35
+ if predicate.call(first.first, second.first) <= 0
36
+ result << first.shift
37
+ else
38
+ result << second.shift
39
+ end
41
40
  end
41
+ result.concat(first).concat(second)
42
42
  end
43
- result.concat(first).concat(second)
44
43
  end
45
- end
46
44
 
47
- # A Track is a list of events.
48
- #
49
- # When you modify the +events+ array, make sure to call recalc_times so
50
- # each Event gets its +time_from_start+ recalculated.
51
- #
52
- # A Track also holds a bitmask that specifies the channels used by the track.
53
- # This bitmask is set when the track is read from the MIDI file by an
54
- # IO::SeqReader but is _not_ kept up to date by any other methods.
45
+ # A Track is a list of events.
46
+ #
47
+ # When you modify the +events+ array, make sure to call recalc_times so
48
+ # each Event gets its +time_from_start+ recalculated.
49
+ #
50
+ # A Track also holds a bitmask that specifies the channels used by the track.
51
+ # This bitmask is set when the track is read from the MIDI file by an
52
+ # IO::SeqReader but is _not_ kept up to date by any other methods.
55
53
 
56
- class Track
54
+ class Track
57
55
 
58
56
  include Enumerable
59
57
 
@@ -63,62 +61,58 @@ class Track
63
61
  attr_reader :sequence
64
62
 
65
63
  def initialize(sequence)
66
- @sequence = sequence
67
- @events = Array.new()
64
+ @sequence = sequence
65
+ @events = Array.new()
68
66
 
69
- # Bitmask of all channels used. Set when track is read in from
70
- # a MIDI file.
71
- @channels_used = 0
67
+ # Bitmask of all channels used. Set when track is read in from
68
+ # a MIDI file.
69
+ @channels_used = 0
72
70
  end
73
71
 
74
72
  # Return track name. If there is no name, return UNNAMED.
75
73
  def name
76
- event = @events.detect { | e |
77
- e.kind_of?(MetaEvent) && e.meta_type == META_SEQ_NAME
78
- }
79
- return event ? event.data_as_str : UNNAMED
74
+ event = @events.detect { |e| e.kind_of?(MetaEvent) && e.meta_type == META_SEQ_NAME }
75
+ event ? event.data_as_str : UNNAMED
80
76
  end
81
77
 
82
78
  # Set track name. Replaces or creates a name meta-event.
83
79
  def name=(name)
84
- event = @events.detect { | e |
85
- e.kind_of?(MetaEvent) && e.meta_type == META_SEQ_NAME
86
- }
87
- if event
88
- event.data = name
89
- else
90
- event = MetaEvent.new(META_SEQ_NAME, name, 0)
91
- @events[0, 0] = event
92
- end
80
+ event = @events.detect { |e| e.kind_of?(MetaEvent) && e.meta_type == META_SEQ_NAME }
81
+ if event
82
+ event.data = name
83
+ else
84
+ event = MetaEvent.new(META_SEQ_NAME, name, 0)
85
+ @events[0, 0] = event
86
+ end
93
87
  end
94
88
 
95
89
  def instrument
96
- MetaEvent.bytes_as_str(@instrument)
90
+ MetaEvent.bytes_as_str(@instrument)
97
91
  end
98
92
 
99
93
  def instrument=(str_or_bytes)
100
- @instrument = case str_or_bytes
101
- when String
102
- MetaEvent.str_as_bytes(str_or_bytes)
103
- else
104
- str_or_bytes
105
- end
94
+ @instrument = case str_or_bytes
95
+ when String
96
+ MetaEvent.str_as_bytes(str_or_bytes)
97
+ else
98
+ str_or_bytes
99
+ end
106
100
  end
107
101
 
108
102
  # Merges an array of events into our event list. After merging, the
109
103
  # events' time_from_start values are correct so you don't need to worry
110
104
  # about calling recalc_times.
111
105
  def merge(event_list)
112
- @events = merge_event_lists(@events, event_list)
106
+ @events = merge_event_lists(@events, event_list)
113
107
  end
114
108
 
115
109
  # Merges two event arrays together. Does not modify this track.
116
110
  def merge_event_lists(list1, list2)
117
- recalc_times(0, list1)
118
- recalc_times(0, list2)
119
- list = list1 + list2
120
- recalc_delta_from_times(0, list)
121
- return list
111
+ recalc_times(0, list1)
112
+ recalc_times(0, list2)
113
+ list = list1 + list2
114
+ recalc_delta_from_times(0, list)
115
+ return list
122
116
  end
123
117
 
124
118
  # Quantize every event. length_or_note is either a length (1 = quarter,
@@ -128,24 +122,24 @@ class Track
128
122
  # Since each event's time_from_start is modified, we call
129
123
  # recalc_delta_from_times after each event quantizes itself.
130
124
  def quantize(length_or_note)
131
- delta = case length_or_note
132
- when String
133
- @sequence.note_to_delta(length_or_note)
134
- else
135
- @sequence.length_to_delta(length_or_note.to_i)
136
- end
137
- @events.each { | event | event.quantize_to(delta) }
138
- recalc_delta_from_times
125
+ delta = case length_or_note
126
+ when String
127
+ @sequence.note_to_delta(length_or_note)
128
+ else
129
+ @sequence.length_to_delta(length_or_note.to_i)
130
+ end
131
+ @events.each { |event| event.quantize_to(delta) }
132
+ recalc_delta_from_times
139
133
  end
140
134
 
141
135
  # Recalculate start times for all events in +list+ from starting_at to
142
136
  # end.
143
137
  def recalc_times(starting_at=0, list=@events)
144
- t = (starting_at == 0) ? 0 : list[starting_at - 1].time_from_start
145
- list[starting_at .. -1].each { | e |
146
- t += e.delta_time
147
- e.time_from_start = t
148
- }
138
+ t = (starting_at == 0) ? 0 : list[starting_at - 1].time_from_start
139
+ list[starting_at .. -1].each do |e|
140
+ t += e.delta_time
141
+ e.time_from_start = t
142
+ end
149
143
  end
150
144
 
151
145
  # The opposite of recalc_times: recalculates delta_time for each event
@@ -153,23 +147,23 @@ class Track
153
147
  # merging two event lists. As a side-effect, elements from starting_at
154
148
  # are sorted by time_from_start.
155
149
  def recalc_delta_from_times(starting_at=0, list=@events)
156
- prev_time_from_start = 0
157
- # We need to sort the sublist. sublist.sort! does not do what we want.
158
- # We call mergesort instead of Array.sort because sort is not stable
159
- # (it can mix up the order of events that have the same start time).
160
- # See http://wiki.github.com/adamjmurray/cosy/midilib-notes for details.
161
- list[starting_at .. -1] = MIDI::Array.new(list[starting_at .. -1]).mergesort { | e1, e2 |
162
- e1.time_from_start <=> e2.time_from_start
163
- }
164
- list[starting_at .. -1].each { | e |
165
- e.delta_time = e.time_from_start - prev_time_from_start
166
- prev_time_from_start = e.time_from_start
167
- }
150
+ prev_time_from_start = 0
151
+ # We need to sort the sublist. sublist.sort! does not do what we want.
152
+ # We call mergesort instead of Array.sort because sort is not stable
153
+ # (it can mix up the order of events that have the same start time).
154
+ # See http://wiki.github.com/adamjmurray/cosy/midilib-notes for details.
155
+ list[starting_at .. -1] = MIDI::Array.new(list[starting_at .. -1]).mergesort do |e1, e2|
156
+ e1.time_from_start <=> e2.time_from_start
157
+ end
158
+ list[starting_at .. -1].each do |e|
159
+ e.delta_time = e.time_from_start - prev_time_from_start
160
+ prev_time_from_start = e.time_from_start
161
+ end
168
162
  end
169
163
 
170
164
  # Iterate over events.
171
165
  def each # :yields: event
172
- @events.each { | event | yield event }
166
+ @events.each { |event| yield event }
173
167
  end
174
168
 
175
169
  # Sort events by their time_from_start. After sorting,
@@ -180,6 +174,6 @@ class Track
180
174
  # the events first. This method may go away in a future release, or at
181
175
  # least be aliased to recalc_delta_from_times.
182
176
  alias_method :sort, :recalc_delta_from_times
183
- end
177
+ end
184
178
 
185
179
  end