midilib 2.0.4 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +2 -1
  3. data/Credits +44 -2
  4. data/README.rdoc +13 -9
  5. data/Rakefile +36 -53
  6. data/TODO.rdoc +13 -2
  7. data/examples/from_scratch.rb +4 -6
  8. data/examples/measures_mbt.rb +11 -11
  9. data/examples/print_program_changes.rb +11 -11
  10. data/examples/reader2text.rb +191 -191
  11. data/examples/seq2text.rb +18 -18
  12. data/examples/split.rb +21 -20
  13. data/examples/strings.rb +15 -15
  14. data/examples/transpose.rb +41 -42
  15. data/html/MIDI/ActiveSense.html +89 -213
  16. data/html/MIDI/ChannelEvent.html +95 -224
  17. data/html/MIDI/ChannelPressure.html +103 -241
  18. data/html/MIDI/Clock.html +89 -213
  19. data/html/MIDI/Continue.html +89 -213
  20. data/html/MIDI/Controller.html +105 -246
  21. data/html/MIDI/Event.html +134 -358
  22. data/html/MIDI/IO/MIDIFile.html +544 -1148
  23. data/html/MIDI/IO/SeqReader.html +273 -577
  24. data/html/MIDI/IO/SeqWriter.html +233 -439
  25. data/html/MIDI/IO.html +48 -164
  26. data/html/MIDI/KeySig.html +148 -291
  27. data/html/MIDI/Marker.html +73 -192
  28. data/html/MIDI/Measure.html +104 -267
  29. data/html/MIDI/Measures.html +106 -259
  30. data/html/MIDI/MetaEvent.html +171 -352
  31. data/html/MIDI/NoteEvent.html +114 -276
  32. data/html/MIDI/NoteOff.html +95 -223
  33. data/html/MIDI/NoteOn.html +95 -223
  34. data/html/MIDI/PitchBend.html +104 -242
  35. data/html/MIDI/PolyPressure.html +102 -246
  36. data/html/MIDI/ProgramChange.html +103 -241
  37. data/html/MIDI/Realtime.html +96 -230
  38. data/html/MIDI/Sequence.html +256 -576
  39. data/html/MIDI/SongPointer.html +104 -242
  40. data/html/MIDI/SongSelect.html +103 -241
  41. data/html/MIDI/Start.html +89 -213
  42. data/html/MIDI/Stop.html +89 -213
  43. data/html/MIDI/SystemCommon.html +73 -192
  44. data/html/MIDI/SystemExclusive.html +106 -244
  45. data/html/MIDI/SystemReset.html +89 -213
  46. data/html/MIDI/Tempo.html +127 -309
  47. data/html/MIDI/TimeSig.html +119 -300
  48. data/html/MIDI/Track.html +214 -494
  49. data/html/MIDI/TuneRequest.html +96 -230
  50. data/html/MIDI/Utils.html +91 -233
  51. data/html/MIDI.html +142 -526
  52. data/html/Object.html +197 -0
  53. data/html/README_rdoc.html +280 -486
  54. data/html/TODO_rdoc.html +68 -145
  55. data/html/created.rid +15 -14
  56. data/html/css/fonts.css +167 -0
  57. data/html/css/rdoc.css +639 -0
  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 +230 -446
  69. data/html/js/darkfish.js +22 -91
  70. data/html/js/navigation.js +4 -41
  71. data/html/js/navigation.js.gz +0 -0
  72. data/html/js/search.js +41 -25
  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 +9 -8
  76. data/html/js/searcher.js.gz +0 -0
  77. data/html/table_of_contents.html +1111 -505
  78. data/install.rb +53 -34
  79. data/lib/midilib/consts.rb +406 -408
  80. data/lib/midilib/event.rb +335 -306
  81. data/lib/midilib/info.rb +5 -7
  82. data/lib/midilib/io/midifile.rb +424 -452
  83. data/lib/midilib/io/seqreader.rb +200 -192
  84. data/lib/midilib/io/seqwriter.rb +151 -147
  85. data/lib/midilib/measure.rb +78 -80
  86. data/lib/midilib/mergesort.rb +39 -0
  87. data/lib/midilib/sequence.rb +93 -87
  88. data/lib/midilib/track.rb +71 -118
  89. data/lib/midilib/utils.rb +17 -20
  90. data/lib/midilib.rb +5 -5
  91. data/test/event_equality.rb +50 -52
  92. data/test/test_event.rb +120 -124
  93. data/test/test_io.rb +118 -38
  94. data/test/test_mergesort.rb +37 -0
  95. data/test/test_midifile.rb +6 -19
  96. data/test/test_sequence.rb +62 -61
  97. data/test/test_track.rb +126 -155
  98. data/test/test_varlen.rb +23 -27
  99. metadata +67 -62
  100. data/html/IO.html +0 -259
  101. data/html/MIDI/MIDI/MIDI/Array.html +0 -353
  102. data/html/MIDI/MIDI/MIDI.html +0 -204
  103. data/html/MIDI/MIDI.html +0 -204
  104. data/html/js/jquery.js +0 -18
  105. data/html/rdoc.css +0 -543
@@ -20,202 +20,202 @@ require 'midilib/io/midifile'
20
20
  DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
21
21
 
22
22
  class TextTranslator < MIDI::IO::MIDIFile
23
-
24
- def initialize(seq, proc = nil)
25
- super()
26
- @seq = seq
27
- @track = nil
28
- @update_block = block_given?() ? Proc.new() : proc
29
- end
30
-
31
- # Generate a unique number for a channel/note combination. This is used
32
- # to remember pending note on events.
33
- def note_hash(chan, note)
34
- return (chan << 8) + note
35
- end
36
-
37
- # Print a delta time.
38
- def pdelta
39
- print "#{@curr_ticks}: "
40
- end
41
-
42
- # The remaining methods are overrides of methods in MIDI::IO::MIDIFile.
43
-
44
- def header(format, ntrks, division)
45
- puts "header: format = #{format}, ntrks = #{ntrks}," +
46
- " division = #{division}"
47
-
48
- @ntrks = ntrks
49
- @update_block.call(nil, @ntrks, 0) if @update_block
50
- end
51
-
52
- def start_track()
53
- pdelta()
54
- puts "track start"
55
-
56
- @pending = []
57
- @chan_mask = 0
58
- end
59
-
60
- def end_track()
61
- pdelta()
62
- puts "track end; chans used bitmask = #{@chan_mask}"
63
- # Write message for any pending note on messages
64
- @pending.each_with_index { | num, chan |
65
- puts "pending note off missing for chan #{num >> 8}," +
66
- " note #{num & 0xff}" if note_obj
67
- }
68
- @pending = nil
69
-
70
- # call update block
71
- @update_block.call(@track, @ntrks, @seq.tracks.length) if @update_block
72
- end
73
-
74
- def note_on(chan, note, vel)
75
- pdelta()
76
- if vel == 0
77
- print "(note on, vel 0) "
78
- note_off(chan, note, 64)
79
- return
80
- end
81
-
82
- puts "note on chan #{chan}, note #{note}, vel #{vel}"
83
- @pending << note_hash(chan, note)
84
- track_uses_channel(chan)
85
- end
86
-
87
- def note_off(chan, note, vel)
88
- pdelta()
89
- # Find note on, create note off, connect the two, and remove
90
- # note on from pending list.
91
- pnum = note_hash(chan, note)
92
- @pending.each_with_index { | num, i |
93
- if pnum == num
94
- puts "note off chan #{chan}, note #{note}, vel #{vel}"
95
- @pending.delete_at(i)
96
- return
97
- end
98
- }
99
- puts "note off with no earlier note on (ch #{chan}, note" +
100
- " #{note}, vel #{vel})"
101
- end
102
-
103
- def pressure(chan, note, press)
104
- pdelta()
105
- puts "pressure chan #{chan}, note #{note}, press #{press}"
106
- track_uses_channel(chan)
107
- end
108
-
109
- def controller(chan, control, value)
110
- pdelta()
111
- puts "controller chan #{chan}, control #{control}, value #{value}"
112
- track_uses_channel(chan)
113
- end
114
-
115
- def pitch_bend(chan, msb, lsb)
116
- pdelta()
117
- puts "pitch bend chan #{chan}, msb #{msb}, lsb #{lsb}"
118
- track_uses_channel(chan)
119
- end
120
-
121
- def program(chan, program)
122
- pdelta()
123
- puts "program chan #{chan}, program #{program}"
124
- track_uses_channel(chan)
125
- end
126
-
127
- def chan_pressure(chan, press)
128
- pdelta()
129
- puts "chan press chan #{chan}, press #{press}"
130
- track_uses_channel(chan)
131
- end
132
-
133
- def sysex(msg)
134
- pdelta()
135
- puts "sysex size #{msg.length}"
136
- end
137
-
138
- def meta_misc(type, msg)
139
- pdelta()
140
- puts "meta misc type #{type}, length #{msg.length}"
141
- end
142
-
143
- def sequencer_specific(type, msg)
144
- pdelta()
145
- puts "sequencer specific type #{type}, msg #{msg.length}"
146
- end
147
-
148
- def sequence_number(num)
149
- pdelta()
150
- puts "sequence number #{num}"
151
- end
152
-
153
- def text(type, msg)
154
- pdelta()
155
- msg = MIDI::MetaEvent.bytes_as_str(msg)
156
- case type
157
- when MIDI::META_SEQ_NAME
158
- puts "seq or track name #{msg}"
159
- when MIDI::META_INSTRUMENT
160
- puts "instrument name #{msg}"
161
- when MIDI::META_MARKER
162
- puts "marker #{msg}"
163
- else
164
- puts "text = #{msg}, type = #{type}"
165
- end
166
- end
167
-
168
- def eot()
169
- pdelta()
170
- puts "end of track event"
171
- end
172
-
173
- def time_signature(numer, denom, clocks, qnotes)
174
- pdelta()
175
- puts "time sig numer #{numer}, denom #{denom}, clocks #{clocks}," +
176
- " qnotes #{qnotes}"
177
- end
178
-
179
- def smpte(hour, min, sec, frame, fract)
180
- pdelta()
181
- puts "smpte #{hour}:#{min}.#{sec}, frame #{frame}, fract #{fract}"
182
- end
183
-
184
- def tempo(microsecs)
185
- pdelta()
186
- bpm = 1.0 / microsecs # quarter notes per microsecond
187
- bpm *= 1000000.0 # quarter notes per second
188
- bpm *= 60.0 # quarter notes per minute
189
- puts "tempo microsecs pqn = #{microsecs} (#{bpm} bpm)"
190
- end
191
-
192
- def key_signature(sharpflat, is_minor)
193
- pdelta()
194
- puts "key sig sharpflat #{sharpflat}, is_minor #{is_minor}"
195
- end
196
-
197
- def arbitrary(msg)
198
- pdelta()
199
- puts "arbitrary length = #{msg.length}"
200
- end
201
-
202
- def track_uses_channel(chan)
203
- @chan_mask = @chan_mask | (1 << chan)
204
- end
205
-
23
+ def initialize(seq, &block)
24
+ super()
25
+ @seq = seq
26
+ @track = nil
27
+ @update_block = block
28
+ end
29
+
30
+ # Generate a unique number for a channel/note combination. This is used
31
+ # to remember pending note on events.
32
+ def note_hash(chan, note)
33
+ (chan << 8) + note
34
+ end
35
+
36
+ # Print a delta time.
37
+ def pdelta
38
+ print "#{@curr_ticks}: "
39
+ end
40
+
41
+ # The remaining methods are overrides of methods in MIDI::IO::MIDIFile.
42
+
43
+ def header(format, ntrks, division)
44
+ puts "header: format = #{format}, ntrks = #{ntrks}," +
45
+ " division = #{division}"
46
+
47
+ @ntrks = ntrks
48
+ @update_block.call(nil, @ntrks, 0) if @update_block
49
+ end
50
+
51
+ def start_track
52
+ pdelta
53
+ puts 'track start'
54
+
55
+ @pending = []
56
+ @chan_mask = 0
57
+ end
58
+
59
+ def end_track
60
+ pdelta
61
+ puts "track end; chans used bitmask = #{@chan_mask}"
62
+ # Write message for any pending note on messages
63
+ @pending.each_with_index do |num, chan|
64
+ if note_obj
65
+ puts "pending note off missing for chan #{num >> 8}," +
66
+ " note #{num & 0xff}"
67
+ end
68
+ end
69
+ @pending = nil
70
+
71
+ # call update block
72
+ @update_block.call(@track, @ntrks, @seq.tracks.length) if @update_block
73
+ end
74
+
75
+ def note_on(chan, note, vel)
76
+ pdelta
77
+ if vel == 0
78
+ print '(note on, vel 0) '
79
+ note_off(chan, note, 64)
80
+ return
81
+ end
82
+
83
+ puts "note on chan #{chan}, note #{note}, vel #{vel}"
84
+ @pending << note_hash(chan, note)
85
+ track_uses_channel(chan)
86
+ end
87
+
88
+ def note_off(chan, note, vel)
89
+ pdelta
90
+ # Find note on, create note off, connect the two, and remove
91
+ # note on from pending list.
92
+ pnum = note_hash(chan, note)
93
+ @pending.each_with_index do |num, i|
94
+ next unless pnum == num
95
+
96
+ puts "note off chan #{chan}, note #{note}, vel #{vel}"
97
+ @pending.delete_at(i)
98
+ return
99
+ end
100
+ puts "note off with no earlier note on (ch #{chan}, note" +
101
+ " #{note}, vel #{vel})"
102
+ end
103
+
104
+ def pressure(chan, note, press)
105
+ pdelta
106
+ puts "pressure chan #{chan}, note #{note}, press #{press}"
107
+ track_uses_channel(chan)
108
+ end
109
+
110
+ def controller(chan, control, value)
111
+ pdelta
112
+ puts "controller chan #{chan}, control #{control}, value #{value}"
113
+ track_uses_channel(chan)
114
+ end
115
+
116
+ def pitch_bend(chan, msb, lsb)
117
+ pdelta
118
+ puts "pitch bend chan #{chan}, msb #{msb}, lsb #{lsb}"
119
+ track_uses_channel(chan)
120
+ end
121
+
122
+ def program(chan, program)
123
+ pdelta
124
+ puts "program chan #{chan}, program #{program}"
125
+ track_uses_channel(chan)
126
+ end
127
+
128
+ def chan_pressure(chan, press)
129
+ pdelta
130
+ puts "chan press chan #{chan}, press #{press}"
131
+ track_uses_channel(chan)
132
+ end
133
+
134
+ def sysex(msg)
135
+ pdelta
136
+ puts "sysex size #{msg.length}"
137
+ end
138
+
139
+ def meta_misc(type, msg)
140
+ pdelta
141
+ puts "meta misc type #{type}, length #{msg.length}"
142
+ end
143
+
144
+ def sequencer_specific(type, msg)
145
+ pdelta
146
+ puts "sequencer specific type #{type}, msg #{msg.length}"
147
+ end
148
+
149
+ def sequence_number(num)
150
+ pdelta
151
+ puts "sequence number #{num}"
152
+ end
153
+
154
+ def text(type, msg)
155
+ pdelta
156
+ msg = MIDI::MetaEvent.bytes_as_str(msg)
157
+ case type
158
+ when MIDI::META_SEQ_NAME
159
+ puts "seq or track name #{msg}"
160
+ when MIDI::META_INSTRUMENT
161
+ puts "instrument name #{msg}"
162
+ when MIDI::META_MARKER
163
+ puts "marker #{msg}"
164
+ else
165
+ puts "text = #{msg}, type = #{type}"
166
+ end
167
+ end
168
+
169
+ def eot
170
+ pdelta
171
+ puts 'end of track event'
172
+ end
173
+
174
+ def time_signature(numer, denom, clocks, qnotes)
175
+ pdelta
176
+ puts "time sig numer #{numer}, denom #{denom}, clocks #{clocks}," +
177
+ " qnotes #{qnotes}"
178
+ end
179
+
180
+ def smpte(hour, min, sec, frame, fract)
181
+ pdelta
182
+ puts "smpte #{hour}:#{min}.#{sec}, frame #{frame}, fract #{fract}"
183
+ end
184
+
185
+ def tempo(microsecs)
186
+ pdelta
187
+ bpm = 1.0 / microsecs # quarter notes per microsecond
188
+ bpm *= 1_000_000.0 # quarter notes per second
189
+ bpm *= 60.0 # quarter notes per minute
190
+ puts "tempo microsecs pqn = #{microsecs} (#{bpm} bpm)"
191
+ end
192
+
193
+ def key_signature(sharpflat, is_minor)
194
+ pdelta
195
+ puts "key sig sharpflat #{sharpflat}, is_minor #{is_minor}"
196
+ end
197
+
198
+ def arbitrary(msg)
199
+ pdelta
200
+ puts "arbitrary length = #{msg.length}"
201
+ end
202
+
203
+ def track_uses_channel(chan)
204
+ @chan_mask |= (1 << chan)
205
+ end
206
206
  end
207
207
 
208
208
  # ================================================================
209
209
 
210
- seq = MIDI::Sequence.new()
210
+ seq = MIDI::Sequence.new
211
211
 
212
212
  # Specify what class to use when reading the MIDI file.
213
213
  seq.reader_class = TextTranslator
214
214
 
215
- File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
216
- # The block we pass in to Sequence.read is called at the end of every
217
- # track read. It is optional, but is useful for progress reports.
218
- seq.read(file) { | track, num_tracks, i |
219
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
220
- }
221
- }
215
+ File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
216
+ # The block we pass in to Sequence.read is called at the end of every
217
+ # track read. It is optional, but is useful for progress reports.
218
+ seq.read(file) do |track, num_tracks, i|
219
+ puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
220
+ end
221
+ end
data/examples/seq2text.rb CHANGED
@@ -19,23 +19,23 @@ require 'midilib/sequence'
19
19
  DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
20
20
 
21
21
  # Read from MIDI file
22
- seq = MIDI::Sequence.new()
22
+ seq = MIDI::Sequence.new
23
23
 
24
- File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
25
- # The block we pass in to Sequence.read is called at the end of every
26
- # track read. It is optional, but is useful for progress reports.
27
- seq.read(file) { | track, num_tracks, i |
28
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
29
- }
30
- }
24
+ File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
25
+ # The block we pass in to Sequence.read is called at the end of every
26
+ # track read. It is optional, but is useful for progress reports.
27
+ seq.read(file) do |track, num_tracks, i|
28
+ puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
29
+ end
30
+ end
31
31
 
32
- seq.each { | track |
33
- puts "*** track name \"#{track.name}\""
34
- puts "instrument name \"#{track.instrument}\""
35
- puts "#{track.events.length} events"
36
- track.each { | e |
37
- e.print_decimal_numbers = true # default = false (print hex)
38
- e.print_note_names = true # default = false (print note numbers)
39
- puts e
40
- }
41
- }
32
+ seq.each do |track|
33
+ puts "*** track name \"#{track.name}\""
34
+ puts "instrument name \"#{track.instrument}\""
35
+ puts "#{track.events.length} events"
36
+ track.each do |e|
37
+ e.print_decimal_numbers = true # default = false (print hex)
38
+ e.print_note_names = true # default = false (print note numbers)
39
+ puts e
40
+ end
41
+ end
data/examples/split.rb CHANGED
@@ -22,31 +22,32 @@ DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
22
22
  filename = ARGV[0]
23
23
  include_tempo_track = true
24
24
  if filename == '-x'
25
- include_tempo_track = false
26
- filename = ARGV[1]
25
+ include_tempo_track = false
26
+ filename = ARGV[1]
27
27
  end
28
28
 
29
29
  # Read from MIDI file
30
- seq = MIDI::Sequence.new()
30
+ seq = MIDI::Sequence.new
31
31
 
32
- File.open(filename || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
33
- # The block we pass in to Sequence.read is called at the end of every
34
- # track read. It is optional, but is useful for progress reports.
35
- seq.read(file) { | track, num_tracks, i |
36
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
37
- }
38
- }
32
+ File.open(filename || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
33
+ # The block we pass in to Sequence.read is called at the end of every
34
+ # track read. It is optional, but is useful for progress reports.
35
+ seq.read(file) do |track, num_tracks, i|
36
+ puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
37
+ end
38
+ end
39
39
 
40
40
  t0 = seq.tracks[0]
41
41
  unless include_tempo_track
42
- s = MIDI::Sequence.new
43
- s.tracks << t0
44
- File.open("tempo_track.mid", 'wb') { | file | s.write(file) }
42
+ s = MIDI::Sequence.new
43
+ s.tracks << t0
44
+ File.open('tempo_track.mid', 'wb') { |file| s.write(file) }
45
+ end
46
+ seq.each_with_index do |track, i|
47
+ next unless i > 0
48
+
49
+ s = MIDI::Sequence.new
50
+ s.tracks << t0 if include_tempo_track
51
+ s.tracks << track
52
+ File.open("#{track.name}.mid", 'wb') { |file| s.write(file) }
45
53
  end
46
- seq.each_with_index { | track, i |
47
- next unless i > 0
48
- s = MIDI::Sequence.new
49
- s.tracks << t0 if include_tempo_track
50
- s.tracks << track
51
- File.open("#{track.name}.mid", 'wb') { | file | s.write(file) }
52
- }
data/examples/strings.rb CHANGED
@@ -15,20 +15,20 @@ require 'midilib/consts'
15
15
 
16
16
  DEFAULT_MIDI_TEST_FILE = 'NoFences.mid'
17
17
 
18
- seq = MIDI::Sequence.new()
19
- File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') { | file |
20
- # The block we pass in to Sequence.read is called at the end of every
21
- # track read. It is optional, but is useful for progress reports.
22
- seq.read(file) { | track, num_tracks, i |
23
- puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
24
- }
25
- }
18
+ seq = MIDI::Sequence.new
19
+ File.open(ARGV[0] || DEFAULT_MIDI_TEST_FILE, 'rb') do |file|
20
+ # The block we pass in to Sequence.read is called at the end of every
21
+ # track read. It is optional, but is useful for progress reports.
22
+ seq.read(file) do |track, num_tracks, i|
23
+ puts "read track #{track ? track.name : ''} (#{i} of #{num_tracks})"
24
+ end
25
+ end
26
26
 
27
27
  include MIDI
28
- seq.each { | track |
29
- track.each { | event |
30
- puts event.data if event.kind_of?(MIDI::MetaEvent) &&
31
- [META_TEXT, META_COPYRIGHT, META_SEQ_NAME, META_INSTRUMENT,
32
- META_LYRIC, META_CUE, META_MARKER].include?(event.meta_type)
33
- }
34
- }
28
+ seq.each do |track|
29
+ track.each do |event|
30
+ puts event.data if event.is_a?(MIDI::MetaEvent) &&
31
+ [META_TEXT, META_COPYRIGHT, META_SEQ_NAME, META_INSTRUMENT,
32
+ META_LYRIC, META_CUE, META_MARKER].include?(event.meta_type)
33
+ end
34
+ end
@@ -17,59 +17,58 @@ require 'midilib/sequence'
17
17
  require 'midilib/io/seqreader'
18
18
  require 'midilib/io/seqwriter'
19
19
 
20
-
21
20
  def usage
22
- $stderr.print <<EOF
23
- usage: #{$0} [--channel|-c channel] [--transpose|-t half_steps]
24
- input_midi_file output_midi_file
25
-
26
- --channel|-c channel 1-16; default is 1
27
- --transpose|-t half_steps default = 12 (one octave up)
28
- EOF
29
- exit(1)
21
+ $stderr.print <<~EOF
22
+ usage: #{$0} [--channel|-c channel] [--transpose|-t half_steps]
23
+ input_midi_file output_midi_file
24
+ #{' '}
25
+ --channel|-c channel 1-16; default is 1
26
+ --transpose|-t half_steps default = 12 (one octave up)
27
+ EOF
28
+ exit(1)
30
29
  end
31
30
 
32
31
  transpose = 12
33
32
  channel = 0
34
33
 
35
34
  g = GetoptLong.new(['--transpose', '-t', GetoptLong::REQUIRED_ARGUMENT],
36
- ['--channel', '-c', GetoptLong::REQUIRED_ARGUMENT])
37
- g.each { | name, arg |
38
- case name
39
- when '--transpose'
40
- transpose = arg.to_i
41
- when '--channel'
42
- channel = arg.to_i - 1
43
- else
44
- usage()
45
- end
46
- }
35
+ ['--channel', '-c', GetoptLong::REQUIRED_ARGUMENT])
36
+ g.each do |name, arg|
37
+ case name
38
+ when '--transpose'
39
+ transpose = arg.to_i
40
+ when '--channel'
41
+ channel = arg.to_i - 1
42
+ else
43
+ usage
44
+ end
45
+ end
47
46
 
48
- usage() unless ARGV.length >= 2
47
+ usage unless ARGV.length >= 2
49
48
 
50
- seq = MIDI::Sequence.new()
51
- File.open(ARGV[0], 'rb') { | file |
52
- # The block we pass in to Sequence.read is called at the end of every
53
- # track read. It is optional, but is useful for progress reports.
54
- seq.read(file) { | num_tracks, i |
55
- puts "read track #{i} of #{num_tracks}"
56
- }
57
- }
49
+ seq = MIDI::Sequence.new
50
+ File.open(ARGV[0], 'rb') do |file|
51
+ # The block we pass in to Sequence.read is called at the end of every
52
+ # track read. It is optional, but is useful for progress reports.
53
+ seq.read(file) do |num_tracks, i|
54
+ puts "read track #{i} of #{num_tracks}"
55
+ end
56
+ end
57
+
58
+ seq.each do |track|
59
+ track.each do |event|
60
+ next unless event.is_a?(MIDI::NoteEvent) && event.channel == channel
58
61
 
59
- seq.each { | track |
60
- track.each { | event |
61
- if event.kind_of?(MIDI::NoteEvent) && event.channel == channel
62
- val = event.note + transpose
63
- if val < 0 || val > 127
64
- $stderr.puts "transposition out of range; ignored"
65
- else
66
- event.note = val
67
- end
68
- end
69
- }
70
- }
62
+ val = event.note + transpose
63
+ if val < 0 || val > 127
64
+ warn 'transposition out of range; ignored'
65
+ else
66
+ event.note = val
67
+ end
68
+ end
69
+ end
71
70
 
72
71
  # Output to named file or stdout.
73
72
  file = ARGV[1] ? File.open(ARGV[1], 'wb') : $stdout
74
73
  seq.write(file)
75
- file.close() if ARGV[1]
74
+ file.close if ARGV[1]