midilib 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/ChangeLog +3 -1
  2. data/Credits +6 -1
  3. data/README.rdoc +41 -15
  4. data/Rakefile +3 -11
  5. data/TODO.rdoc +4 -7
  6. data/examples/from_scratch.rb +2 -2
  7. data/examples/measures_mbt.rb +1 -1
  8. data/examples/print_program_changes.rb +1 -1
  9. data/examples/strings.rb +1 -1
  10. data/examples/transpose.rb +1 -1
  11. data/html/Array.html +382 -0
  12. data/html/IO.html +277 -0
  13. data/html/MIDI.html +829 -0
  14. data/html/MIDI/ActiveSense.html +317 -0
  15. data/html/MIDI/ChannelEvent.html +347 -0
  16. data/html/MIDI/ChannelPressure.html +379 -0
  17. data/html/MIDI/Clock.html +317 -0
  18. data/html/MIDI/Continue.html +317 -0
  19. data/html/MIDI/Controller.html +398 -0
  20. data/html/MIDI/Event.html +659 -0
  21. data/html/MIDI/IO.html +238 -0
  22. data/html/MIDI/IO/MIDIFile.html +2269 -0
  23. data/html/MIDI/IO/SeqReader.html +1051 -0
  24. data/html/MIDI/IO/SeqWriter.html +706 -0
  25. data/html/MIDI/KeySig.html +487 -0
  26. data/html/MIDI/Marker.html +275 -0
  27. data/html/MIDI/Measure.html +479 -0
  28. data/html/MIDI/Measures.html +416 -0
  29. data/html/MIDI/MetaEvent.html +617 -0
  30. data/html/MIDI/NoteEvent.html +459 -0
  31. data/html/MIDI/NoteOff.html +341 -0
  32. data/html/MIDI/NoteOn.html +341 -0
  33. data/html/MIDI/PitchBend.html +380 -0
  34. data/html/MIDI/PolyPressure.html +390 -0
  35. data/html/MIDI/ProgramChange.html +379 -0
  36. data/html/MIDI/Realtime.html +354 -0
  37. data/html/MIDI/Sequence.html +1063 -0
  38. data/html/MIDI/SongPointer.html +380 -0
  39. data/html/MIDI/SongSelect.html +379 -0
  40. data/html/MIDI/Start.html +317 -0
  41. data/html/MIDI/Stop.html +317 -0
  42. data/html/MIDI/SystemCommon.html +275 -0
  43. data/html/MIDI/SystemExclusive.html +382 -0
  44. data/html/MIDI/SystemReset.html +317 -0
  45. data/html/MIDI/Tempo.html +519 -0
  46. data/html/MIDI/TimeSig.html +524 -0
  47. data/html/MIDI/Track.html +859 -0
  48. data/html/MIDI/TuneRequest.html +354 -0
  49. data/html/MIDI/Utils.html +350 -0
  50. data/html/README_rdoc.html +882 -0
  51. data/html/TODO_rdoc.html +215 -0
  52. data/html/created.rid +14 -0
  53. data/html/images/brick.png +0 -0
  54. data/html/images/brick_link.png +0 -0
  55. data/html/images/bug.png +0 -0
  56. data/html/images/bullet_black.png +0 -0
  57. data/html/images/bullet_toggle_minus.png +0 -0
  58. data/html/images/bullet_toggle_plus.png +0 -0
  59. data/html/images/date.png +0 -0
  60. data/html/images/find.png +0 -0
  61. data/html/images/loadingAnimation.gif +0 -0
  62. data/html/images/macFFBgHack.png +0 -0
  63. data/html/images/package.png +0 -0
  64. data/html/images/page_green.png +0 -0
  65. data/html/images/page_white_text.png +0 -0
  66. data/html/images/page_white_width.png +0 -0
  67. data/html/images/plugin.png +0 -0
  68. data/html/images/ruby.png +0 -0
  69. data/html/images/tag_green.png +0 -0
  70. data/html/images/wrench.png +0 -0
  71. data/html/images/wrench_orange.png +0 -0
  72. data/html/images/zoom.png +0 -0
  73. data/html/index.html +1266 -0
  74. data/html/js/darkfish.js +116 -0
  75. data/html/js/jquery.js +32 -0
  76. data/html/js/quicksearch.js +114 -0
  77. data/html/js/thickbox-compressed.js +10 -0
  78. data/html/lib/midilib/consts_rb.html +55 -0
  79. data/html/lib/midilib/event_rb.html +56 -0
  80. data/html/lib/midilib/info_rb.html +52 -0
  81. data/html/lib/midilib/io/midifile_rb.html +54 -0
  82. data/html/lib/midilib/io/seqreader_rb.html +58 -0
  83. data/html/lib/midilib/io/seqwriter_rb.html +59 -0
  84. data/html/lib/midilib/measure_rb.html +54 -0
  85. data/html/lib/midilib/sequence_rb.html +58 -0
  86. data/html/lib/midilib/track_rb.html +54 -0
  87. data/html/lib/midilib/utils_rb.html +52 -0
  88. data/html/lib/midilib_rb.html +71 -0
  89. data/html/rdoc.css +706 -0
  90. data/install.rb +1 -1
  91. data/lib/midilib/event.rb +11 -77
  92. data/lib/midilib/info.rb +4 -4
  93. data/lib/midilib/io/seqreader.rb +2 -2
  94. data/lib/midilib/io/seqwriter.rb +1 -1
  95. data/lib/midilib/sequence.rb +1 -1
  96. data/lib/midilib/track.rb +54 -8
  97. data/test/test_event.rb +4 -62
  98. data/test/test_sequence.rb +1 -1
  99. data/test/test_track.rb +39 -5
  100. metadata +102 -9
@@ -0,0 +1,882 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: README.rdoc [midilib]</title>
10
+
11
+ <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="./js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="./js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="./js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="./js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file">
24
+ <div id="metadata">
25
+ <div id="home-metadata">
26
+ <div id="home-section" class="section">
27
+ <h3 class="section-header">
28
+ <a href="./index.html">Home</a>
29
+ <a href="./index.html#classes">Classes</a>
30
+ <a href="./index.html#methods">Methods</a>
31
+ </h3>
32
+ </div>
33
+ </div>
34
+
35
+ <div id="project-metadata">
36
+
37
+
38
+ <div id="fileindex-section" class="section project-section">
39
+ <h3 class="section-header">Files</h3>
40
+ <ul>
41
+
42
+ <li class="file"><a href="./README_rdoc.html">README.rdoc</a></li>
43
+
44
+ <li class="file"><a href="./TODO_rdoc.html">TODO.rdoc</a></li>
45
+
46
+ </ul>
47
+ </div>
48
+
49
+
50
+ <div id="classindex-section" class="section project-section">
51
+ <h3 class="section-header">Class Index
52
+ <span class="search-toggle"><img src="./images/find.png"
53
+ height="16" width="16" alt="[+]"
54
+ title="show/hide quicksearch" /></span></h3>
55
+ <form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
56
+ <fieldset>
57
+ <legend>Quicksearch</legend>
58
+ <input type="text" name="quicksearch" value=""
59
+ class="quicksearch-field" />
60
+ </fieldset>
61
+ </form>
62
+
63
+ <ul class="link-list">
64
+
65
+ <li><a href="./MIDI.html">MIDI</a></li>
66
+
67
+ <li><a href="./MIDI/ActiveSense.html">MIDI::ActiveSense</a></li>
68
+
69
+ <li><a href="./MIDI/ChannelEvent.html">MIDI::ChannelEvent</a></li>
70
+
71
+ <li><a href="./MIDI/ChannelPressure.html">MIDI::ChannelPressure</a></li>
72
+
73
+ <li><a href="./MIDI/Clock.html">MIDI::Clock</a></li>
74
+
75
+ <li><a href="./MIDI/Continue.html">MIDI::Continue</a></li>
76
+
77
+ <li><a href="./MIDI/Controller.html">MIDI::Controller</a></li>
78
+
79
+ <li><a href="./MIDI/Event.html">MIDI::Event</a></li>
80
+
81
+ <li><a href="./MIDI/IO.html">MIDI::IO</a></li>
82
+
83
+ <li><a href="./MIDI/IO/MIDIFile.html">MIDI::IO::MIDIFile</a></li>
84
+
85
+ <li><a href="./MIDI/IO/SeqReader.html">MIDI::IO::SeqReader</a></li>
86
+
87
+ <li><a href="./MIDI/IO/SeqWriter.html">MIDI::IO::SeqWriter</a></li>
88
+
89
+ <li><a href="./MIDI/KeySig.html">MIDI::KeySig</a></li>
90
+
91
+ <li><a href="./MIDI/Marker.html">MIDI::Marker</a></li>
92
+
93
+ <li><a href="./MIDI/Measure.html">MIDI::Measure</a></li>
94
+
95
+ <li><a href="./MIDI/Measures.html">MIDI::Measures</a></li>
96
+
97
+ <li><a href="./MIDI/MetaEvent.html">MIDI::MetaEvent</a></li>
98
+
99
+ <li><a href="./MIDI/NoteEvent.html">MIDI::NoteEvent</a></li>
100
+
101
+ <li><a href="./MIDI/NoteOff.html">MIDI::NoteOff</a></li>
102
+
103
+ <li><a href="./MIDI/NoteOff.html">MIDI::NoteOff</a></li>
104
+
105
+ <li><a href="./MIDI/NoteOn.html">MIDI::NoteOn</a></li>
106
+
107
+ <li><a href="./MIDI/NoteOn.html">MIDI::NoteOn</a></li>
108
+
109
+ <li><a href="./MIDI/PitchBend.html">MIDI::PitchBend</a></li>
110
+
111
+ <li><a href="./MIDI/PolyPressure.html">MIDI::PolyPressure</a></li>
112
+
113
+ <li><a href="./MIDI/ProgramChange.html">MIDI::ProgramChange</a></li>
114
+
115
+ <li><a href="./MIDI/Realtime.html">MIDI::Realtime</a></li>
116
+
117
+ <li><a href="./MIDI/Sequence.html">MIDI::Sequence</a></li>
118
+
119
+ <li><a href="./MIDI/SongPointer.html">MIDI::SongPointer</a></li>
120
+
121
+ <li><a href="./MIDI/SongSelect.html">MIDI::SongSelect</a></li>
122
+
123
+ <li><a href="./MIDI/Start.html">MIDI::Start</a></li>
124
+
125
+ <li><a href="./MIDI/Stop.html">MIDI::Stop</a></li>
126
+
127
+ <li><a href="./MIDI/SystemCommon.html">MIDI::SystemCommon</a></li>
128
+
129
+ <li><a href="./MIDI/SystemExclusive.html">MIDI::SystemExclusive</a></li>
130
+
131
+ <li><a href="./MIDI/SystemReset.html">MIDI::SystemReset</a></li>
132
+
133
+ <li><a href="./MIDI/Tempo.html">MIDI::Tempo</a></li>
134
+
135
+ <li><a href="./MIDI/TimeSig.html">MIDI::TimeSig</a></li>
136
+
137
+ <li><a href="./MIDI/Track.html">MIDI::Track</a></li>
138
+
139
+ <li><a href="./MIDI/TuneRequest.html">MIDI::TuneRequest</a></li>
140
+
141
+ <li><a href="./MIDI/Utils.html">MIDI::Utils</a></li>
142
+
143
+ <li><a href="./Array.html">Array</a></li>
144
+
145
+ <li><a href="./IO.html">IO</a></li>
146
+
147
+ </ul>
148
+ <div id="no-class-search-results" style="display: none;">No matching classes.</div>
149
+ </div>
150
+
151
+
152
+ </div>
153
+ </div>
154
+
155
+ <div id="documentation">
156
+ <h1>midilib</h1>
157
+ <p>
158
+ midilib is a pure Ruby <a href="MIDI.html">MIDI</a> library useful for
159
+ reading and writing standard <a href="MIDI.html">MIDI</a> files and
160
+ manipulating <a href="MIDI.html">MIDI</a> event data. Classes include <a
161
+ href="MIDI/Sequence.html">MIDI::Sequence</a>, <a
162
+ href="MIDI/Track.html">MIDI::Track</a>, <a
163
+ href="MIDI/Event.html">MIDI::Event</a>, and <a
164
+ href="MIDI/IO/MIDIFile.html">MIDI::IO::MIDIFile</a> and its subclasses <a
165
+ href="MIDI/IO/SeqReader.html">MIDI::IO::SeqReader</a> and <a
166
+ href="MIDI/IO/SeqWriter.html">MIDI::IO::SeqWriter</a>.
167
+ </p>
168
+ <p>
169
+ The GitHub project page and Web site of midilib is <a
170
+ href="http://github.com/jimm/midilib">github.com/jimm/midilib</a> and the
171
+ RubyGems.org page is <a
172
+ href="http://rubygems.org/gems/midilib">rubygems.org/gems/midilib</a>,
173
+ where you can also find all the RDoc documentation.
174
+ </p>
175
+ <p>
176
+ midilib is compatible with both Ruby 1.8.x and 1.9.x.
177
+ </p>
178
+ <h2>Dependencies</h2>
179
+ <p>
180
+ midilib does not require any other packages. The test suite in the tests
181
+ directory requires the testing framework TestUnit, which comes with Ruby
182
+ 1.8 and later and can also be found in the Ruby Application Archive (<a
183
+ href="http://raa.ruby-lang.org">raa.ruby-lang.org</a>).
184
+ </p>
185
+ <p>
186
+ To rebuild the gem or RDocs or run the tests easily, you can use the
187
+ Rakefile which requires Rake (<a
188
+ href="http://rake.rubyforge.org">rake.rubyforge.org</a>).
189
+ </p>
190
+ <h2>Installation</h2>
191
+ <h3>RubyGems Installation</h3>
192
+ <p>
193
+ To install midilib as a gem, type
194
+ </p>
195
+ <pre>
196
+ % gem install midilib
197
+ </pre>
198
+ <p>
199
+ or
200
+ </p>
201
+ <pre>
202
+ % gem update midilib
203
+ </pre>
204
+ <p>
205
+ if you already have a previous version. You may need root privileges to
206
+ install or update the gem.
207
+ </p>
208
+ <h3>Manual Installation</h3>
209
+ <p>
210
+ After downloading and expanding the archive, you can install midilib with
211
+ the command
212
+ </p>
213
+ <pre>
214
+ % ruby install.rb
215
+ </pre>
216
+ <p>
217
+ (or)
218
+ </p>
219
+ <pre>
220
+ % ruby install.rb --install-dir=my_directory
221
+ </pre>
222
+ <p>
223
+ You may need root privileges to install.
224
+ </p>
225
+ <h2>Testing</h2>
226
+ <pre>
227
+ % rake test
228
+ </pre>
229
+ <p>
230
+ runs all of the tests in the test directory.
231
+ </p>
232
+ <h2>Overview</h2>
233
+ <p>
234
+ <a href="MIDI.html">MIDI</a> file <a href="IO.html">IO</a> only understands
235
+ <a href="MIDI.html">MIDI</a> file format 1, where a sequence is made up of
236
+ multiple tracks. It doesn&#8217;t yet understand format 0 (a single track
237
+ containing all events) or format 2 (a collection of format 0 files in one
238
+ file).
239
+ </p>
240
+ <h3><a href="MIDI/Sequence.html">MIDI::Sequence</a></h3>
241
+ <p>
242
+ A sequence contains a collection of tracks and global information like the
243
+ sequence&#8217;s pulses per quarter note (ppqn) and time signature.
244
+ </p>
245
+ <p>
246
+ The first track in a sequence is special; it holds meta-events like tempo
247
+ and sequence name. Don&#8217;t put any notes in this track.
248
+ </p>
249
+ <p>
250
+ <a href="MIDI/Sequence.html">MIDI::Sequence</a> also contains some
251
+ convenience methods that let you set and retrieve the sequence&#8217;s
252
+ name, the time signature, and to retrieve the first tempo event&#8217;s
253
+ beats-per-minute value.
254
+ </p>
255
+ <p>
256
+ Normally instances of <a
257
+ href="MIDI/IO/SeqReader.html">MIDI::IO::SeqReader</a> and <a
258
+ href="MIDI/IO/SeqWriter.html">MIDI::IO::SeqWriter</a> are used when a
259
+ sequence reads itself from or writes itself to a <a
260
+ href="MIDI.html">MIDI</a> file. You can change that by setting a
261
+ sequence&#8217;s reader_class or writer_class attributes. Instances of the
262
+ classes contained in those attributes are created and used whenever the
263
+ sequence reads or writes itself.
264
+ </p>
265
+ <h3><a href="MIDI/Track.html">MIDI::Track</a></h3>
266
+ <p>
267
+ A track contains an array of events.
268
+ </p>
269
+ <p>
270
+ When you modify the <tt>events</tt> array, make sure to call recalc_times
271
+ so each event gets its <tt>time_from_start</tt> recalculated. You
272
+ don&#8217;t have to do that after every event you add; just remember to do
273
+ so before using the track in a way that expects the list of events to be
274
+ ordered correctly.
275
+ </p>
276
+ <p>
277
+ A Track also holds a bit mask that specifies the channels used by the
278
+ track. This bit mask is set when the track is read from the <a
279
+ href="MIDI.html">MIDI</a> file by a SeqReader but is <em>not</em> kept up
280
+ to date by any other methods. Specifically, if you add events to a track at
281
+ any other time, the bit mask will not be updated.
282
+ </p>
283
+ <h3><a href="MIDI/Measure.html">MIDI::Measure</a></h3>
284
+ <p>
285
+ This class contains information about a measure from the sequence. Measure
286
+ data is based on the time signature information from the sequence and is
287
+ not stored in the sequence itself.
288
+ </p>
289
+ <h3><a href="MIDI/Measures.html">MIDI::Measures</a></h3>
290
+ <p>
291
+ The class <a href="MIDI/Sequence.html">MIDI::Sequence</a> method
292
+ get_measures returns a <a href="MIDI/Measures.html">MIDI::Measures</a>
293
+ object. <a href="MIDI/Measures.html">MIDI::Measures</a> is a subclass of <a
294
+ href="Array.html">Array</a>. It is a specialized container for <a
295
+ href="MIDI/Measure.html">MIDI::Measure</a> objects, which can be use to map
296
+ event times to measure numbers. Please note that this object has to be
297
+ remade when events are deleted/added in the sequence.
298
+ </p>
299
+ <p>
300
+ <a href="MIDI/Measure.html">MIDI::Measure</a> and <a
301
+ href="MIDI/Measures.html">MIDI::Measures</a> are brought to us by Jari
302
+ Williamsson <jari.williamsson@mailbox.swipnet.se>, who also contributed
303
+ some improvements to the <a href="MIDI/Event.html">MIDI::Event</a> and <a
304
+ href="MIDI/Track.html">MIDI::Track</a> classes.
305
+ </p>
306
+ <h3><a href="MIDI/Event.html">MIDI::Event</a></h3>
307
+ <p>
308
+ Each event holds not only its delta time but also its time from the start
309
+ of the track. The track is responsible for recalculating its events&#8217;
310
+ start times. You can call <a
311
+ href="MIDI/Track.html#method-i-recalc_times">MIDI::Track#recalc_times</a>
312
+ to do so.
313
+ </p>
314
+ <p>
315
+ Events have a number of boolean methods that identify their types, like
316
+ channel?, note?, note_on?, note_off?, meta?, system?, realtime?, and
317
+ program_change?. Events know how to print themselves. By default, all
318
+ numbers are printed as hexidecimal and channel numbers are printed from
319
+ 0-15. Setting print_decimal_numbers to true will output decimal numbers and
320
+ setting print_channel_numbers_from_one will output channel numbers from
321
+ 1-16.
322
+ </p>
323
+ <p>
324
+ Subclasses of <a href="MIDI/Event.html">MIDI::Event</a> implement the
325
+ various <a href="MIDI.html">MIDI</a> messages such as note on and off,
326
+ controller values, system exclusive data, and realtime bytes.
327
+ </p>
328
+ <p>
329
+ <a href="MIDI/Realtime.html">MIDI::Realtime</a> events have delta values
330
+ and start times, just like all the other midilib event types do. (<a
331
+ href="MIDI.html">MIDI</a> real time status bytes don&#8217;t have delta
332
+ times, but this way we can record when in a track the realtime byte was
333
+ received and should be sent. This is useful for start/continue/stop events
334
+ that control other devices, for example.) Note that when a <a
335
+ href="MIDI/Realtime.html">MIDI::Realtime</a> event is written out to a <a
336
+ href="MIDI.html">MIDI</a> file, the delta time is not written.
337
+ </p>
338
+ <p>
339
+ <a href="MIDI/MetaEvent.html">MIDI::MetaEvent</a> events hold an array of
340
+ bytes named &#8216;data&#8217;. Many meta events are string holders (text,
341
+ lyric, marker, etc.) Though the &#8216;data&#8217; value is always an array
342
+ of bytes, <a href="MIDI/MetaEvent.html">MIDI::MetaEvent</a> helps with
343
+ saving and accessing string. The <a
344
+ href="MIDI/MetaEvent.html#method-i-data_as_str">MIDI::MetaEvent#data_as_str</a>
345
+ method returns the data bytes as a string. When assigning to a meta
346
+ event&#8217;s data, if you pass in a string it will get converted to an
347
+ array of bytes.
348
+ </p>
349
+ <h2>How To Use</h2>
350
+ <p>
351
+ The following examples show you how to use midilib to read, write, and
352
+ manipulate <a href="MIDI.html">MIDI</a> files and modify track events. See
353
+ also the files in the examples directory, which are described below.
354
+ </p>
355
+ <h3>Reading a <a href="MIDI.html">MIDI</a> File</h3>
356
+ <p>
357
+ To read a <a href="MIDI.html">MIDI</a> file, create a <a
358
+ href="MIDI/Sequence.html">MIDI::Sequence</a> object and call its # method,
359
+ passing in an <a href="IO.html">IO</a> object.
360
+ </p>
361
+ <p>
362
+ The # method takes an optional block. If present, the block is called once
363
+ after each track has finished being read. Each time, it is passed the total
364
+ number of tracks and the number of the current track that has just been
365
+ read. This is useful for notifying the user of progress, for example by
366
+ updating a GUI progress bar.
367
+ </p>
368
+ <pre>
369
+ require 'midilib/io/seqreader'
370
+
371
+ # Create a new, empty sequence.
372
+ seq = MIDI::Sequence.new()
373
+
374
+ # Read the contents of a MIDI file into the sequence.
375
+ File.open('my_midi_file.mid', 'rb') { | file |
376
+ seq.read(file) { | num_tracks, i |
377
+ # Print something when each track is read.
378
+ puts &quot;read track #{i} of #{num_tracks}&quot;
379
+ }
380
+ }
381
+ </pre>
382
+ <h3>Writing a <a href="MIDI.html">MIDI</a> File</h3>
383
+ <p>
384
+ To write a <a href="MIDI.html">MIDI</a> file, call the write method,
385
+ passing in an <a href="IO.html">IO</a> object.
386
+ </p>
387
+ <pre>
388
+ require 'midilib/io/seqwriter'
389
+
390
+ # Start with a sequence that has something worth saving.
391
+ seq = read_or_create_seq_we_care_not_how()
392
+
393
+ # Write the sequence to a MIDI file.
394
+ File.open('my_output_file.mid', 'wb') { | file | seq.write(file) }
395
+ </pre>
396
+ <h3>Editing a <a href="MIDI.html">MIDI</a> File</h3>
397
+ <p>
398
+ Combining the last two examples, here is a script that reads a <a
399
+ href="MIDI.html">MIDI</a> file, transposes some events, and writes the
400
+ sequence out to a different file. This is a useful template for
401
+ programatically manipulating <a href="MIDI.html">MIDI</a> data.
402
+ </p>
403
+ <p>
404
+ This code transposes all of the note events (note on, note off, and poly
405
+ pressure) on channel 5 down one octave. It&#8217;s easy to find events that
406
+ need to be transposed: the method # returns true.
407
+ </p>
408
+ <h4>Transposing One Channel</h4>
409
+ <pre>
410
+ require 'midilib/io/seqreader'
411
+ require 'midilib/io/seqwriter'
412
+
413
+ # Create a new, empty sequence.
414
+ seq = MIDI::Sequence.new()
415
+
416
+ # Read the contents of a MIDI file into the sequence.
417
+ File.open('my_input_file.mid', 'rb') { | file |
418
+ seq.read(file) { | num_tracks, i |
419
+ # Print something when each track is read.
420
+ puts &quot;read track #{i} of #{num_tracks}&quot;
421
+ }
422
+ }
423
+
424
+ # Iterate over every event in every track.
425
+ seq.each { | track |
426
+ track.each { | event |
427
+ # If the event is a note event (note on, note off, or poly
428
+ # pressure) and it is on MIDI channel 5 (channels start at
429
+ # 0, so we use 4), then transpose the event down one octave.
430
+ if event.note? &amp;&amp; event.channel == 4
431
+ event.note -= 12
432
+ end
433
+ }
434
+ }
435
+
436
+ # Write the sequence to a MIDI file.
437
+ File.open('my_output_file.mid', 'wb') { | file | seq.write(file) }
438
+ </pre>
439
+ <h3>Manipulating tracks</h3>
440
+ <p>
441
+ If you modify a track&#8217;s list of events directly, don&#8217;t forget
442
+ to call <a
443
+ href="MIDI/Track.html#method-i-recalc_times">MIDI::Track#recalc_times</a>
444
+ when you are done.
445
+ </p>
446
+ <pre>
447
+ track.events[42, 1] = array_of_events
448
+ track.events &lt;&lt; an_event
449
+ track.merge(array_of_events)
450
+ track.recalc_times
451
+ </pre>
452
+ <h3>Calculating delta times</h3>
453
+ <p>
454
+ A few methods in <a href="MIDI/Sequence.html">MIDI::Sequence</a> make it
455
+ easier to calculate the delta times that represent note lengths. <a
456
+ href="MIDI/Sequence.html#method-i-length_to_delta">MIDI::Sequence#length_to_delta</a>
457
+ takes a note length (a multiple of a quarter note) and returns the delta
458
+ time given the sequence&#8217;s current ppqn (pulses per quarter note)
459
+ setting. 1 is a quarter note, 1.0/32.0 is a 32nd note (use floating-point
460
+ numbers to avoid integer rounding), 1.5 is a dotted quarter, etc. See the
461
+ documentation for that method for more information.
462
+ </p>
463
+ <p>
464
+ <a
465
+ href="MIDI/Sequence.html#method-i-note_to_length">MIDI::Sequence#note_to_length</a>
466
+ takes a note name and returns a length value (again, as a multiple of a
467
+ quarter note). Legal note names are those found in
468
+ MIDI::Sequence::NOTE_TO_LENGTH, and may begin with &#8220;dotted&#8221;
469
+ and/or end with &#8220;triplet&#8221;. For example, &#8220;whole&#8221;,
470
+ &#8220;sixteenth&#8221;, &#8220;32nd&#8221;, &#8220;quarter triplet&#8221;,
471
+ &#8220;dotted 16th&#8221;, and &#8220;dotted 8th triplet&#8221; are all
472
+ legal note names.
473
+ </p>
474
+ <p>
475
+ Finally, <a
476
+ href="MIDI/Sequence.html#method-i-note_to_delta">MIDI::Sequence#note_to_delta</a>
477
+ takes a note name and returns a delta time. It does this by calling
478
+ note_to_length, then passing the result to length_to_delta.
479
+ </p>
480
+ <h3>Example Scripts</h3>
481
+ <p>
482
+ Here are short descriptions of each of the examples found in the examples
483
+ directory.
484
+ </p>
485
+ <ul>
486
+ <li><p>
487
+ examples/from_scratch.rb shows you how to create a new sequence from
488
+ scratch and save it to a <a href="MIDI.html">MIDI</a> file. It creates a
489
+ file called &#8216;from_scratch.mid&#8217;.
490
+ </p>
491
+ </li>
492
+ <li><p>
493
+ examples/seq2text.rb dumps a <a href="MIDI.html">MIDI</a> file as text. It
494
+ reads in a sequence and uses the to_s method of each event.
495
+ </p>
496
+ </li>
497
+ <li><p>
498
+ examples/reader2text.rb dumps a <a href="MIDI.html">MIDI</a> file as text.
499
+ It subclasses MIDI::SeqReader instead of creating a sequence containing
500
+ tracks and events.
501
+ </p>
502
+ </li>
503
+ <li><p>
504
+ examples/transpose.rb transposes all note events (note on, note off, poly
505
+ pressure) on a specified channel by a specified amount.
506
+ </p>
507
+ </li>
508
+ <li><p>
509
+ There is also one <a href="MIDI.html">MIDI</a> file, examples/NoFences.mid.
510
+ It is a little pop ditty I wrote. The instruments in this file use General
511
+ <a href="MIDI.html">MIDI</a> patch numbers and drum note assignments. Since
512
+ I don&#8217;t normally use GM patches, the sounds used here are at best
513
+ approximations of the sounds I use.
514
+ </p>
515
+ </li>
516
+ </ul>
517
+ <h2>Resources</h2>
518
+ <p>
519
+ The Ruby Web site (<a
520
+ href="http://www.ruby-lang.org/en/index.html">www.ruby-lang.org/en/index.html</a>)
521
+ contains an introduction to Ruby, the Ruby Application Archive (RAA) at <a
522
+ href="http://raa.ruby-lang.org">raa.ruby-lang.org</a>, and pointers to more
523
+ information.
524
+ </p>
525
+ <p>
526
+ <cite>Programming Ruby, The Pragmatic Programmer&#8217;s Guide</cite>, by
527
+ David Thomas and Andrew Hunt, is a well-written and practical introduction
528
+ to Ruby. Its Web page at <a
529
+ href="http://www.rubycentral.com/book">www.rubycentral.com/book</a> also
530
+ contains a wealth of Ruby information. Though the first edition book is
531
+ available online, I encourage you to purchase a copy of the latest edition.
532
+ </p>
533
+ <p>
534
+ A description of the <a href="MIDI.html">MIDI</a> file format can be found
535
+ in a few places such as <a
536
+ href="http://www.borg.com/~jglatt/tech/midifile.htm.">www.borg.com/~jglatt/tech/midifile.htm.</a>
537
+ </p>
538
+ <p>
539
+ The <a href="MIDI.html">MIDI</a> message reference at <a
540
+ href="http://www.io.com/~jimm/midi_ref.html">www.io.com/~jimm/midi_ref.html</a>
541
+ describes the format of <a href="MIDI.html">MIDI</a> commands.
542
+ </p>
543
+ <h1>To Do</h1>
544
+ <h2>Bugs</h2>
545
+ <p>
546
+ No known bugs. (If that&#8217;s not a challenge, I don&#8217;t know what
547
+ is.)
548
+ </p>
549
+ <h2>Features</h2>
550
+ <ul>
551
+ <li><h1>print_decimal_numbers= and =print_channel_numbers_from_one= should be</h1>
552
+ <p>
553
+ associated with sequence, or perhaps track, not event.
554
+ </p>
555
+ </li>
556
+ <li><p>
557
+ Method to translate event&#8217;s time_from_start to number of milliseconds
558
+ from start.
559
+ </p>
560
+ </li>
561
+ <li><p>
562
+ Swing quantizing. (Implied by list email from Carl Youngblood
563
+ <carl.youngblood@gmail.com>)
564
+ </p>
565
+ </li>
566
+ <li><p>
567
+ Implement key signature in SeqReader.
568
+ </p>
569
+ </li>
570
+ <li><p>
571
+ Format 0 files.
572
+ </p>
573
+ </li>
574
+ <li><p>
575
+ Format 2 files(?).
576
+ </p>
577
+ </li>
578
+ </ul>
579
+ <h2>Documentation</h2>
580
+ <ul>
581
+ <li><p>
582
+ Write better docs.
583
+ </p>
584
+ </li>
585
+ </ul>
586
+ <h2>Tests</h2>
587
+ <ul>
588
+ <li><p>
589
+ Tests for Noah Thorp&#8217;s midilib bug fixes.
590
+ </p>
591
+ </li>
592
+ </ul>
593
+ <h1>Support</h1>
594
+ <ul>
595
+ <li><p>
596
+ Visit the forums, bug list, and mailing list pages at <a
597
+ href="http://rubyforge.org/projects/midilib">rubyforge.org/projects/midilib</a>
598
+ </p>
599
+ </li>
600
+ <li><p>
601
+ Send email to Jim Menard at <a href="mailto:jimm@io.com">jimm@io.com</a>
602
+ </p>
603
+ </li>
604
+ <li><p>
605
+ Ask on the ruby-talk mailing list
606
+ </p>
607
+ </li>
608
+ </ul>
609
+ <h1>Administrivia</h1>
610
+ <table>
611
+ <tr><td valign="top">Author</td><td><p>
612
+ Jim Menard (<a href="mailto:jimm@io.com">jimm@io.com</a>)
613
+ </p>
614
+ </td></tr>
615
+ <tr><td valign="top">Copyright</td><td><p>
616
+ Copyright &#169; 2003-2010 Jim Menard
617
+ </p>
618
+ </td></tr>
619
+ <tr><td valign="top">License</td><td><p>
620
+ Distributed under the same license as Ruby.
621
+ </p>
622
+ </td></tr>
623
+ </table>
624
+ <h2>Copying</h2>
625
+ <p>
626
+ midilib is copyrighted free software by Jim Menard and is released under
627
+ the same license as Ruby. See the Ruby license at <a
628
+ href="http://www.ruby-lang.org/en/LICENSE.txt.">www.ruby-lang.org/en/LICENSE.txt.</a>
629
+ </p>
630
+ <p>
631
+ midilib may be freely copied in its entirety providing this notice, all
632
+ source code, all documentation, and all other files are included.
633
+ </p>
634
+ <p>
635
+ midilib is Copyright &#169; 2003-2010 by Jim Menard.
636
+ </p>
637
+ <p>
638
+ The song &#8220;No Fences&#8221; contained in the <a
639
+ href="MIDI.html">MIDI</a> file examples/NoFences.mid is Copyright &#169;
640
+ 1992 by Jim Menard (jimm@io.com). It may be freely used for non-commercial
641
+ purposes as long as the author is given credit.
642
+ </p>
643
+ <h3>Recent Changes</h3>
644
+ <h4>Changes for 2.0.0:</h4>
645
+ <p>
646
+ <a href="MIDI/NoteOn.html">MIDI::NoteOnEvent</a> and <a
647
+ href="MIDI/NoteOff.html">MIDI::NoteOffEvent</a> renamed to <a
648
+ href="MIDI/NoteOn.html">MIDI::NoteOn</a> and <a
649
+ href="MIDI/NoteOff.html">MIDI::NoteOff</a>. The old names will still work
650
+ for a while.
651
+ </p>
652
+ <p>
653
+ The <a href="MIDI/Event.html">MIDI::Event</a> boolean methods like meta?
654
+ and note? have been removed. Use the event classes themselves (for example,
655
+ <a href="MIDI/MetaEvent.html">MIDI::MetaEvent</a> === my_event or
656
+ my_event.kind_of?(<a href="MIDI/MetaEvent.html">MIDI::MetaEvent</a>)). Case
657
+ statements that use classes work, too:
658
+ </p>
659
+ <pre>
660
+ case my_event
661
+ when MIDI::NoteOn
662
+ do_this()
663
+ when MIDI::NoteOff
664
+ do_that()
665
+ end
666
+ </pre>
667
+ <p>
668
+ Introduced Adam Murray&#8217;s stable sorting code for <a
669
+ href="MIDI/Track.html#method-i-recalc_delta_from_times">MIDI::Track#recalc_delta_from_times</a>.
670
+ See <a
671
+ href="http://wiki.github.com/adamjmurray/cosy/midilib-notes">wiki.github.com/adamjmurray/cosy/midilib-notes</a>
672
+ and <a
673
+ href="http://github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb">github.com/adamjmurray/cosy/blob/master/lib/cosy/helper/midi_file_renderer_helper.rb</a>
674
+ for details.
675
+ </p>
676
+ <p>
677
+ Aliased <a href="MIDI/Track.html#method-i-sort">MIDI::Track#sort</a> to <a
678
+ href="MIDI/Track.html#method-i-recalc_delta_from_times">MIDI::Track#recalc_delta_from_times</a>,
679
+ since all sort did was sort the events then call recalc_delta_from_times,
680
+ and recalc_delta_from_times sorts the events before doing anything else.
681
+ </p>
682
+ <p>
683
+ MIDI::Tempo#mpq_to_bpm now returns a float.
684
+ </p>
685
+ <h4>Changes for 1.2.0:</h4>
686
+ <p>
687
+ Use byte arrays instead of strings for passing around data. All tests now
688
+ pass for both Ruby 1.8.X and 1.9.X.
689
+ </p>
690
+ <h4>New code repository</h4>
691
+ <p>
692
+ The midilib code is now hosted at Github (<a
693
+ href="http://github.com/jimm/midilib">github.com/jimm/midilib</a>).
694
+ </p>
695
+ <h4>Changes for 1.1.4:</h4>
696
+ <ul>
697
+ <li><p>
698
+ Fixed a bug in KeySig.data_as_bytes. Thanks to Noah Thorp for finding this
699
+ and the bug fixed in 1.1.3.
700
+ </p>
701
+ </li>
702
+ </ul>
703
+ <h4>Changes for 1.1.3:</h4>
704
+ <ul>
705
+ <li><p>
706
+ Fixed the way midilib detects the behavior of IO.getc.
707
+ </p>
708
+ </li>
709
+ </ul>
710
+ <h4>Changes for 1.1.2:</h4>
711
+ <ul>
712
+ <li><p>
713
+ Define <a
714
+ href="MIDI/IO/MIDIFile.html#method-i-getc">MIDI::IO::MIDIFile.getc</a>
715
+ differently for different Ruby versions, instead of checking for
716
+ String.bytes every time we read a byte.
717
+ </p>
718
+ </li>
719
+ </ul>
720
+ <h4>Changes for 1.1.1:</h4>
721
+ <ul>
722
+ <li><p>
723
+ Make <a
724
+ href="MIDI/IO/MIDIFile.html#method-i-getc">MIDI::IO::MIDIFile.getc</a> do
725
+ the right thing for both Ruby 1.8 and 1.9.
726
+ </p>
727
+ </li>
728
+ </ul>
729
+ <h4>Changes for 1.1.0:</h4>
730
+ <ul>
731
+ <li><p>
732
+ Added test/test.mid to list of files to be included when packaging midifile
733
+ for distribution.
734
+ </p>
735
+ </li>
736
+ </ul>
737
+ <h4>Changes for 1.0.0:</h4>
738
+ <ul>
739
+ <li><p>
740
+ Fixed the bug in Track#recalc_delta_from_times found by Christopher Rose.
741
+ </p>
742
+ </li>
743
+ </ul>
744
+ <h4>Changes for 0.8.7:</h4>
745
+ <ul>
746
+ <li><p>
747
+ Fixed the misspelled POLY_PRESSURE constant, thanks to Mario Pehle.
748
+ </p>
749
+ </li>
750
+ </ul>
751
+ <h4>Changes for 0.8.6:</h4>
752
+ <ul>
753
+ <li><p>
754
+ Added missing test/test.mid.
755
+ </p>
756
+ </li>
757
+ </ul>
758
+ <h4>Changes for 0.8.5:</h4>
759
+ <ul>
760
+ <li><p>
761
+ Fixed bugs in <a href="MIDI/PitchBend.html">MIDI::PitchBend</a> reading and
762
+ writing, thanks to Emanuel Borsboom.
763
+ </p>
764
+ </li>
765
+ <li><p>
766
+ Fixed a bug in <a
767
+ href="MIDI/Track.html#method-i-quantize">MIDI::Track#quantize</a>.
768
+ </p>
769
+ </li>
770
+ <li><p>
771
+ The argument to <a
772
+ href="MIDI/Track.html#method-i-quantize">MIDI::Track#quantize</a> has
773
+ changed: it is now either a note name (&#8220;sixteenth&#8221;,
774
+ &#8220;32nd&#8221;, &#8220;8th triplet&#8221;) or a length (1 = quarter,
775
+ 0.25 = sixteenth). This is a drastic change that will break all previous
776
+ calls to quantize. However, since that method was broken already, I
777
+ don&#8217;t feel it&#8217;s a burden to anybody to change the arguments.
778
+ </p>
779
+ </li>
780
+ </ul>
781
+ <h4>Changes for 0.8.4:</h4>
782
+ <ul>
783
+ <li><p>
784
+ Realtime status bytes now set @is_realtime to true and return true when
785
+ realtime? is called.
786
+ </p>
787
+ </li>
788
+ <li><p>
789
+ All system common events now set @is_system to true and return true when
790
+ system? is called, not just system exclusive events.
791
+ </p>
792
+ </li>
793
+ <li><p>
794
+ Added examples/from_scratch.rb, which shows how to create a sequence
795
+ manually.
796
+ </p>
797
+ </li>
798
+ <li><p>
799
+ New <a href="MIDI/Sequence.html">MIDI::Sequence</a> methods that turn note
800
+ length names like &#8220;32nd&#8221;, &#8220;dotted quarter&#8221;, and
801
+ &#8220;16th triplet&#8221; into delta times. See the docs below and
802
+ MIDI::Sequence::length_to_delta, MIDI::Sequence::note_to_length, and
803
+ MIDI::Sequence::note_to_delta.
804
+ </p>
805
+ </li>
806
+ </ul>
807
+ <h4>Changes for 0.8.3:</h4>
808
+ <ul>
809
+ <li><p>
810
+ Added <a
811
+ href="MIDI/NoteEvent.html#method-i-note_to_s">MIDI::NoteEvent.note_to_s</a>,
812
+ which returns note name as a string like &#8220;C4&#8221; or
813
+ &#8220;F#6&#8221;.
814
+ </p>
815
+ </li>
816
+ <li><p>
817
+ Added new boolean attributes to MIDI::Event: @print_decimal_numbers and
818
+ @print_note_names. These are used by all Event to_s methods. See
819
+ examples/seq2text.rb for an example.
820
+ </p>
821
+ </li>
822
+ </ul>
823
+ <h4>Changes for 0.8.2:</h4>
824
+ <ul>
825
+ <li><p>
826
+ Changed MIDI::MetaEvent.type to MIDI::MetaEvent.event_type to avoid runtime
827
+ complaints about Object#type calls.
828
+ </p>
829
+ </li>
830
+ <li><p>
831
+ Added &#8216;b&#8217; binary flag to file open modes for Windows.
832
+ </p>
833
+ </li>
834
+ <li><p>
835
+ Fixed $LOAD_PATH in example files.
836
+ </p>
837
+ </li>
838
+ <li><p>
839
+ Fixed read and write block arguments.
840
+ </p>
841
+ </li>
842
+ <li><p>
843
+ Fixed other example script bugs.
844
+ </p>
845
+ </li>
846
+ </ul>
847
+ <h4>Changes for 0.8.1:</h4>
848
+ <ul>
849
+ <li><p>
850
+ Fixed track sorting.
851
+ </p>
852
+ </li>
853
+ <li><p>
854
+ Fixed track&#8217;s recalc_delta_from_times method.
855
+ </p>
856
+ </li>
857
+ <li><p>
858
+ Fixed event quantization.
859
+ </p>
860
+ </li>
861
+ <li><p>
862
+ More tests and documentation.
863
+ </p>
864
+ </li>
865
+ </ul>
866
+ <h2>Warranty</h2>
867
+ <p>
868
+ This software is provided &#8220;as is&#8221; and without any express or
869
+ implied warranties, including, without limitation, the implied warranties
870
+ of merchantability and fitness for a particular purpose.
871
+ </p>
872
+
873
+ </div>
874
+
875
+ <div id="validator-badges">
876
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
877
+ <p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
878
+ Rdoc Generator</a> 1.1.6</small>.</p>
879
+ </div>
880
+ </body>
881
+ </html>
882
+