midilib 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
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