midilib 0.8.4
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.
- data/ChangeLog +87 -0
- data/Credits +8 -0
- data/README +361 -0
- data/Rakefile +68 -0
- data/TODO +25 -0
- data/examples/NoFences.mid +0 -0
- data/examples/from_scratch.mid +0 -0
- data/examples/from_scratch.rb +56 -0
- data/examples/reader2text.rb +220 -0
- data/examples/seq2text.rb +41 -0
- data/examples/strings.rb +34 -0
- data/examples/transpose.rb +75 -0
- data/html/classes/MIDI.html +738 -0
- data/html/classes/MIDI/ActiveSense.html +156 -0
- data/html/classes/MIDI/ActiveSense.src/M000136.html +18 -0
- data/html/classes/MIDI/ActiveSense.src/M000137.html +18 -0
- data/html/classes/MIDI/ChannelEvent.html +179 -0
- data/html/classes/MIDI/ChannelEvent.src/M000124.html +20 -0
- data/html/classes/MIDI/ChannelEvent.src/M000125.html +18 -0
- data/html/classes/MIDI/ChannelPressure.html +184 -0
- data/html/classes/MIDI/ChannelPressure.src/M000088.html +19 -0
- data/html/classes/MIDI/ChannelPressure.src/M000089.html +21 -0
- data/html/classes/MIDI/ChannelPressure.src/M000090.html +18 -0
- data/html/classes/MIDI/Clock.html +156 -0
- data/html/classes/MIDI/Clock.src/M000134.html +18 -0
- data/html/classes/MIDI/Clock.src/M000135.html +18 -0
- data/html/classes/MIDI/Continue.html +156 -0
- data/html/classes/MIDI/Continue.src/M000132.html +18 -0
- data/html/classes/MIDI/Continue.src/M000133.html +18 -0
- data/html/classes/MIDI/Controller.html +189 -0
- data/html/classes/MIDI/Controller.src/M000129.html +21 -0
- data/html/classes/MIDI/Controller.src/M000130.html +22 -0
- data/html/classes/MIDI/Controller.src/M000131.html +18 -0
- data/html/classes/MIDI/Event.html +424 -0
- data/html/classes/MIDI/Event.src/M000145.html +27 -0
- data/html/classes/MIDI/Event.src/M000146.html +18 -0
- data/html/classes/MIDI/Event.src/M000147.html +18 -0
- data/html/classes/MIDI/Event.src/M000148.html +18 -0
- data/html/classes/MIDI/Event.src/M000149.html +18 -0
- data/html/classes/MIDI/Event.src/M000150.html +18 -0
- data/html/classes/MIDI/Event.src/M000151.html +18 -0
- data/html/classes/MIDI/Event.src/M000152.html +18 -0
- data/html/classes/MIDI/Event.src/M000153.html +18 -0
- data/html/classes/MIDI/Event.src/M000154.html +22 -0
- data/html/classes/MIDI/Event.src/M000155.html +18 -0
- data/html/classes/MIDI/Event.src/M000156.html +18 -0
- data/html/classes/MIDI/Event.src/M000157.html +18 -0
- data/html/classes/MIDI/IO.html +121 -0
- data/html/classes/MIDI/IO/MIDIFile.html +925 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000028.html +22 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000029.html +24 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000030.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000031.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000032.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000033.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000034.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000035.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000036.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000037.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000038.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000039.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000040.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000041.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000042.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000043.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000044.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000045.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000046.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000047.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000048.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000049.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000050.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000051.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000052.html +17 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000053.html +43 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000054.html +34 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000055.html +96 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000056.html +18 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000057.html +48 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000058.html +42 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000059.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000060.html +19 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000061.html +20 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000062.html +21 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000063.html +31 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000064.html +20 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000065.html +22 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000066.html +30 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000067.html +18 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000068.html +20 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000069.html +18 -0
- data/html/classes/MIDI/IO/MIDIFile.src/M000070.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.html +460 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000001.html +22 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000002.html +22 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000003.html +21 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000004.html +34 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000005.html +26 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000006.html +28 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000007.html +21 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000008.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000009.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000010.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000011.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000012.html +19 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000013.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000014.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000015.html +27 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000016.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000017.html +18 -0
- data/html/classes/MIDI/IO/SeqReader.src/M000018.html +18 -0
- data/html/classes/MIDI/IO/SeqWriter.html +267 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000019.html +19 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000020.html +25 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000021.html +22 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000022.html +54 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000023.html +49 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000024.html +21 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000025.html +19 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000026.html +24 -0
- data/html/classes/MIDI/IO/SeqWriter.src/M000027.html +26 -0
- data/html/classes/MIDI/Marker.html +139 -0
- data/html/classes/MIDI/Marker.src/M000107.html +18 -0
- data/html/classes/MIDI/MetaEvent.html +189 -0
- data/html/classes/MIDI/MetaEvent.src/M000167.html +21 -0
- data/html/classes/MIDI/MetaEvent.src/M000168.html +23 -0
- data/html/classes/MIDI/MetaEvent.src/M000169.html +53 -0
- data/html/classes/MIDI/NoteEvent.html +233 -0
- data/html/classes/MIDI/NoteEvent.src/M000091.html +21 -0
- data/html/classes/MIDI/NoteEvent.src/M000092.html +20 -0
- data/html/classes/MIDI/NoteEvent.src/M000093.html +18 -0
- data/html/classes/MIDI/NoteEvent.src/M000094.html +22 -0
- data/html/classes/MIDI/NoteOffEvent.html +169 -0
- data/html/classes/MIDI/NoteOffEvent.src/M000086.html +19 -0
- data/html/classes/MIDI/NoteOffEvent.src/M000087.html +19 -0
- data/html/classes/MIDI/NoteOnEvent.html +169 -0
- data/html/classes/MIDI/NoteOnEvent.src/M000102.html +19 -0
- data/html/classes/MIDI/NoteOnEvent.src/M000103.html +19 -0
- data/html/classes/MIDI/PitchBend.html +184 -0
- data/html/classes/MIDI/PitchBend.src/M000104.html +19 -0
- data/html/classes/MIDI/PitchBend.src/M000105.html +22 -0
- data/html/classes/MIDI/PitchBend.src/M000106.html +18 -0
- data/html/classes/MIDI/PolyPressure.html +186 -0
- data/html/classes/MIDI/PolyPressure.src/M000170.html +18 -0
- data/html/classes/MIDI/PolyPressure.src/M000171.html +18 -0
- data/html/classes/MIDI/PolyPressure.src/M000172.html +18 -0
- data/html/classes/MIDI/PolyPressure.src/M000173.html +19 -0
- data/html/classes/MIDI/ProgramChange.html +184 -0
- data/html/classes/MIDI/ProgramChange.src/M000099.html +19 -0
- data/html/classes/MIDI/ProgramChange.src/M000100.html +21 -0
- data/html/classes/MIDI/ProgramChange.src/M000101.html +18 -0
- data/html/classes/MIDI/Realtime.html +171 -0
- data/html/classes/MIDI/Realtime.src/M000083.html +19 -0
- data/html/classes/MIDI/Realtime.src/M000084.html +20 -0
- data/html/classes/MIDI/Realtime.src/M000085.html +18 -0
- data/html/classes/MIDI/Sequence.html +469 -0
- data/html/classes/MIDI/Sequence.src/M000108.html +28 -0
- data/html/classes/MIDI/Sequence.src/M000109.html +21 -0
- data/html/classes/MIDI/Sequence.src/M000110.html +22 -0
- data/html/classes/MIDI/Sequence.src/M000113.html +18 -0
- data/html/classes/MIDI/Sequence.src/M000114.html +27 -0
- data/html/classes/MIDI/Sequence.src/M000115.html +18 -0
- data/html/classes/MIDI/Sequence.src/M000116.html +19 -0
- data/html/classes/MIDI/Sequence.src/M000117.html +19 -0
- data/html/classes/MIDI/Sequence.src/M000118.html +20 -0
- data/html/classes/MIDI/Sequence.src/M000119.html +19 -0
- data/html/classes/MIDI/Sequence.src/M000120.html +18 -0
- data/html/classes/MIDI/SongPointer.html +184 -0
- data/html/classes/MIDI/SongPointer.src/M000138.html +19 -0
- data/html/classes/MIDI/SongPointer.src/M000139.html +22 -0
- data/html/classes/MIDI/SongPointer.src/M000140.html +18 -0
- data/html/classes/MIDI/SongSelect.html +184 -0
- data/html/classes/MIDI/SongSelect.src/M000126.html +19 -0
- data/html/classes/MIDI/SongSelect.src/M000127.html +21 -0
- data/html/classes/MIDI/SongSelect.src/M000128.html +18 -0
- data/html/classes/MIDI/Start.html +156 -0
- data/html/classes/MIDI/Start.src/M000097.html +18 -0
- data/html/classes/MIDI/Start.src/M000098.html +18 -0
- data/html/classes/MIDI/Stop.html +156 -0
- data/html/classes/MIDI/Stop.src/M000095.html +18 -0
- data/html/classes/MIDI/Stop.src/M000096.html +18 -0
- data/html/classes/MIDI/SystemCommon.html +139 -0
- data/html/classes/MIDI/SystemCommon.src/M000144.html +19 -0
- data/html/classes/MIDI/SystemExclusive.html +184 -0
- data/html/classes/MIDI/SystemExclusive.src/M000141.html +19 -0
- data/html/classes/MIDI/SystemExclusive.src/M000142.html +23 -0
- data/html/classes/MIDI/SystemExclusive.src/M000143.html +18 -0
- data/html/classes/MIDI/SystemReset.html +156 -0
- data/html/classes/MIDI/SystemReset.src/M000081.html +18 -0
- data/html/classes/MIDI/SystemReset.src/M000082.html +18 -0
- data/html/classes/MIDI/Tempo.html +250 -0
- data/html/classes/MIDI/Tempo.src/M000158.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000159.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000160.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000161.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000162.html +18 -0
- data/html/classes/MIDI/Tempo.src/M000163.html +25 -0
- data/html/classes/MIDI/Tempo.src/M000164.html +18 -0
- data/html/classes/MIDI/Track.html +380 -0
- data/html/classes/MIDI/Track.src/M000071.html +23 -0
- data/html/classes/MIDI/Track.src/M000072.html +21 -0
- data/html/classes/MIDI/Track.src/M000073.html +26 -0
- data/html/classes/MIDI/Track.src/M000074.html +18 -0
- data/html/classes/MIDI/Track.src/M000075.html +22 -0
- data/html/classes/MIDI/Track.src/M000076.html +20 -0
- data/html/classes/MIDI/Track.src/M000077.html +22 -0
- data/html/classes/MIDI/Track.src/M000078.html +22 -0
- data/html/classes/MIDI/Track.src/M000079.html +18 -0
- data/html/classes/MIDI/Track.src/M000080.html +19 -0
- data/html/classes/MIDI/TuneRequest.html +171 -0
- data/html/classes/MIDI/TuneRequest.src/M000121.html +18 -0
- data/html/classes/MIDI/TuneRequest.src/M000122.html +20 -0
- data/html/classes/MIDI/TuneRequest.src/M000123.html +18 -0
- data/html/classes/MIDI/Utils.html +190 -0
- data/html/classes/MIDI/Utils.src/M000165.html +20 -0
- data/html/classes/MIDI/Utils.src/M000166.html +25 -0
- data/html/created.rid +1 -0
- data/html/files/README.html +599 -0
- data/html/files/TODO.html +142 -0
- data/html/files/lib/midilib/consts_rb.html +107 -0
- data/html/files/lib/midilib/event_rb.html +109 -0
- data/html/files/lib/midilib/info_rb.html +101 -0
- data/html/files/lib/midilib/io/midifile_rb.html +108 -0
- data/html/files/lib/midilib/io/seqreader_rb.html +110 -0
- data/html/files/lib/midilib/io/seqwriter_rb.html +115 -0
- data/html/files/lib/midilib/sequence_rb.html +109 -0
- data/html/files/lib/midilib/track_rb.html +108 -0
- data/html/files/lib/midilib/utils_rb.html +101 -0
- data/html/files/lib/midilib_rb.html +124 -0
- data/html/fr_class_index.html +59 -0
- data/html/fr_file_index.html +38 -0
- data/html/fr_method_index.html +199 -0
- data/html/index.html +24 -0
- data/html/rdoc-style.css +208 -0
- data/install.rb +57 -0
- data/lib/midilib.rb +16 -0
- data/lib/midilib/consts.rb +422 -0
- data/lib/midilib/event.rb +559 -0
- data/lib/midilib/info.rb +9 -0
- data/lib/midilib/io/midifile.rb +446 -0
- data/lib/midilib/io/seqreader.rb +198 -0
- data/lib/midilib/io/seqwriter.rb +151 -0
- data/lib/midilib/sequence.rb +144 -0
- data/lib/midilib/track.rb +115 -0
- data/lib/midilib/utils.rb +36 -0
- data/test/event_equality.rb +81 -0
- data/test/test_event.rb +116 -0
- data/test/test_io.rb +55 -0
- data/test/test_sequence.rb +68 -0
- data/test/test_track.rb +111 -0
- data/test/test_varlen.rb +40 -0
- metadata +330 -0
data/ChangeLog
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
2005-03-21 Jim Menard <jimm@io.com>
|
|
2
|
+
|
|
3
|
+
* lib/midilib/event.rb (Realtime::initialize): set @is_realtime
|
|
4
|
+
to true, not false.
|
|
5
|
+
(SystemCommon::initialize): moved @is_system = true to here
|
|
6
|
+
(SystemExclusive::initialize): ...from here.
|
|
7
|
+
|
|
8
|
+
2005-03-20 Jim Menard <jimm@io.com>
|
|
9
|
+
|
|
10
|
+
* lib/midilib/sequence.rb (Sequence::note_to_delta): created.
|
|
11
|
+
(Sequence::note_to_length): created.
|
|
12
|
+
(Sequence::length_to_delta): created.
|
|
13
|
+
|
|
14
|
+
* examples/from_scratch.rb: created.
|
|
15
|
+
|
|
16
|
+
2004-07-16 Jim Menard <jimm@io.com>
|
|
17
|
+
|
|
18
|
+
* Version 0.8.3 released.
|
|
19
|
+
|
|
20
|
+
2004-07-10 Jim Menard <jimm@io.com>
|
|
21
|
+
|
|
22
|
+
* lib/midilib/event.rb (NoteEvent::note_to_s): created.
|
|
23
|
+
(Event::number_to_s): created.
|
|
24
|
+
(Event): added @print_note_names and @print_decimal_numbers
|
|
25
|
+
attributes.
|
|
26
|
+
(to_s all classes): use @print_note_names and @print_decimal_numbers
|
|
27
|
+
|
|
28
|
+
2004-06-30 Jim Menard <jimm@io.com>
|
|
29
|
+
|
|
30
|
+
* Version 0.8.2 released.
|
|
31
|
+
|
|
32
|
+
* lib/midilib/event.rb (MetaEvent): changed @type to @meta_type to
|
|
33
|
+
avoid warnings like "Object#type is deprecated; use Object#class".
|
|
34
|
+
|
|
35
|
+
* lib/midilib/track.rb (Track::name): use Event.meta_type (renamed
|
|
36
|
+
from Event.type).
|
|
37
|
+
(Track::name=): use Event.meta_type (renamed from Event.type).
|
|
38
|
+
|
|
39
|
+
* test/event_equality.rb (MIDI::MetaEvent): use meta_type instead
|
|
40
|
+
of type.
|
|
41
|
+
|
|
42
|
+
* examples/transpose.rb: fixed $LOAD_PATH. Added 'b' to file open
|
|
43
|
+
modes for Windows.
|
|
44
|
+
|
|
45
|
+
* examples/strings.rb: fixed $LOAD_PATH. Fixed arguments passed to
|
|
46
|
+
read block. Fixed code that looks for meta events. Added 'b' to
|
|
47
|
+
file open modes for Windows.
|
|
48
|
+
|
|
49
|
+
* examples/seq2text.rb: fixed $LOAD_PATH. Fixed arguments passed
|
|
50
|
+
to read block. Added 'b' to file open modes for Windows.
|
|
51
|
+
|
|
52
|
+
* examples/reader2text.rb: fixed $LOAD_PATH. Fixed TextTranslator
|
|
53
|
+
superclass. Fixed arguments passed to read block. Added 'b' to
|
|
54
|
+
file open modes for Windows.
|
|
55
|
+
|
|
56
|
+
* lib/midilib/io/seqwriter.rb (SeqWriter::initialize): added block
|
|
57
|
+
rdoc comment.
|
|
58
|
+
(SeqWriter::write_to): added track to @update_block args.
|
|
59
|
+
|
|
60
|
+
* lib/midilib/io/seqreader.rb (SeqReader::initialize): added block
|
|
61
|
+
rdoc comment.
|
|
62
|
+
|
|
63
|
+
2004-06-27 Jim Menard <jimm@io.com>
|
|
64
|
+
|
|
65
|
+
* Version 0.8.1 released.
|
|
66
|
+
|
|
67
|
+
* test/test_event.rb: created.
|
|
68
|
+
|
|
69
|
+
* lib/midilib/track.rb: more documentation.
|
|
70
|
+
(Track::sort): sorts by events' time_from_start and modifies
|
|
71
|
+
@events (which wasn't happening before; I forgot to assign the
|
|
72
|
+
sorted results back to @events).
|
|
73
|
+
(Track::recalc_delta_from_times): fixed.
|
|
74
|
+
(Track::quantize): call recalc_delta_from_times.
|
|
75
|
+
|
|
76
|
+
* test/test_track.rb (TrackTester::test_sort): created.
|
|
77
|
+
(TrackTester::test_recalc_delta_from_times): created.
|
|
78
|
+
|
|
79
|
+
* lib/midilib/sequence.rb: more documentation.
|
|
80
|
+
|
|
81
|
+
* lib/midilib/consts.rb: hid some comments from RDoc.
|
|
82
|
+
|
|
83
|
+
* lib/midilib/event.rb: more documentation.
|
|
84
|
+
(Event::realtime): fix quantize_to so it changes the event's
|
|
85
|
+
time_from_start instead of delta_time.
|
|
86
|
+
|
|
87
|
+
* test/*.rb: removed redundant copyright and license notices.
|
data/Credits
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
midilib is developed by Jim Menard, jimm@io.com. Additional bug fixes and
|
|
2
|
+
suggestions have come from:
|
|
3
|
+
|
|
4
|
+
Mike Hall <m3ha11@rcn.com>
|
|
5
|
+
|
|
6
|
+
Found errors in example scripts' $LOAD_PATH and a bug in sequence reading
|
|
7
|
+
block callback arguments. Found a bug in meta events that caused
|
|
8
|
+
"Object#type is deprecated" error messages.
|
data/README
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
= midilib
|
|
2
|
+
|
|
3
|
+
midilib is a pure Ruby MIDI library useful for reading and writing standard
|
|
4
|
+
MIDI files and manipulating MIDI event data. Classes include MIDI::Sequence,
|
|
5
|
+
MIDI::Track, MIDI::Event, and MIDI::IO::MIDIFile and its subclasses
|
|
6
|
+
MIDI::IO::SeqReader and MIDI::IO::SeqWriter.
|
|
7
|
+
|
|
8
|
+
The Web site of midilib is (http://midilib.rubyforge.org). The RubyForge
|
|
9
|
+
project page is http://rubyforge.org/projects/midilib, where the latest
|
|
10
|
+
version of midilib may be downloaded. midilib is also available as a RubyGem.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
=== Recent Changes
|
|
14
|
+
|
|
15
|
+
==== Changes for 0.8.4:
|
|
16
|
+
|
|
17
|
+
* Realtime status bytes now set @is_realtime to true and return true when
|
|
18
|
+
realtime? is called.
|
|
19
|
+
|
|
20
|
+
* All system common events now set @is_system to true and return true when
|
|
21
|
+
system? is called, not just system exclusive events.
|
|
22
|
+
|
|
23
|
+
* Added examples/from_scratch.rb, which shows how to create a sequence
|
|
24
|
+
manually.
|
|
25
|
+
|
|
26
|
+
* New MIDI::Sequence methods that turn note length names like "32nd", "dotted
|
|
27
|
+
quarter", and "16th triplet" into delta times. See the docs below and
|
|
28
|
+
MIDI::Sequence::length_to_delta, MIDI::Sequence::note_to_length, and
|
|
29
|
+
MIDI::Sequence::note_to_delta.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
==== Changes for 0.8.3:
|
|
33
|
+
|
|
34
|
+
* Added MIDI::NoteEvent.note_to_s, which returns note name as a string like
|
|
35
|
+
"C4" or "F#6".
|
|
36
|
+
|
|
37
|
+
* Added new boolean attributes to MIDI::Event: @print_decimal_numbers and
|
|
38
|
+
@print_note_names. These are used by all Event to_s methods. See
|
|
39
|
+
examples/seq2text.rb for an example.
|
|
40
|
+
|
|
41
|
+
==== Changes for 0.8.2:
|
|
42
|
+
|
|
43
|
+
* Changed MIDI::MetaEvent.type to MIDI::MetaEvent.event_type to avoid
|
|
44
|
+
runtime complaints about Object#type calls.
|
|
45
|
+
* Added 'b' binary flag to file open modes for Windows.
|
|
46
|
+
* Fixed $LOAD_PATH in example files.
|
|
47
|
+
* Fixed read and write block arguments.
|
|
48
|
+
* Fixed other example script bugs.
|
|
49
|
+
|
|
50
|
+
==== Changes for 0.8.1:
|
|
51
|
+
|
|
52
|
+
* Fixed track sorting.
|
|
53
|
+
* Fixed track's recalc_delta_from_times method.
|
|
54
|
+
* Fixed event quantization.
|
|
55
|
+
* More tests and documentation.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
== Dependencies
|
|
59
|
+
|
|
60
|
+
midilib does not require any other packages. The test suite in the tests
|
|
61
|
+
directory requires the testing framework TestUnit, which comes with Ruby 1.8
|
|
62
|
+
and later and can also be found in the Ruby Application Archive
|
|
63
|
+
(http://raa.ruby-lang.org).
|
|
64
|
+
|
|
65
|
+
To rebuild the gem or RDocs or run the tests easily, you can use the Rakefile
|
|
66
|
+
which requires Rake (http://rake.rubyforge.org).
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
== Installation
|
|
70
|
+
|
|
71
|
+
=== RubyGems Installation
|
|
72
|
+
|
|
73
|
+
To install midilib as a gem, type
|
|
74
|
+
|
|
75
|
+
% gem install midilib
|
|
76
|
+
|
|
77
|
+
You may need root privileges to install the gem.
|
|
78
|
+
|
|
79
|
+
=== Manual Installation
|
|
80
|
+
|
|
81
|
+
After downloading and expanding the archive, you can install midilib with the
|
|
82
|
+
command
|
|
83
|
+
|
|
84
|
+
% ruby install.rb
|
|
85
|
+
(or)
|
|
86
|
+
% ruby install.rb --install-dir=my_directory
|
|
87
|
+
|
|
88
|
+
You may need root privileges to install.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
== Testing
|
|
92
|
+
|
|
93
|
+
% rake test
|
|
94
|
+
|
|
95
|
+
runs all of the tests in the test directory.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
== Overview
|
|
99
|
+
|
|
100
|
+
MIDI file IO only understands MIDI file format 1, where a sequence is made up
|
|
101
|
+
of multiple tracks. It doesn't yet understand format 0 (a single track
|
|
102
|
+
containing all events) or format 2 (a collection of format 0 files in one
|
|
103
|
+
file).
|
|
104
|
+
|
|
105
|
+
=== MIDI::Sequence
|
|
106
|
+
|
|
107
|
+
A sequence contains a collection of tracks and global information like the
|
|
108
|
+
sequence's pulses per quarter note (ppqn) and time signature.
|
|
109
|
+
|
|
110
|
+
The first track in a sequence is special; it holds meta-events like tempo and
|
|
111
|
+
sequence name. Don't put any notes in this track.
|
|
112
|
+
|
|
113
|
+
MIDI::Sequence also contains some convenience methods that let you set and
|
|
114
|
+
retrieve the sequence's name, the time signature, and to retrieve the first
|
|
115
|
+
tempo event's beats-per-minute value.
|
|
116
|
+
|
|
117
|
+
Normally instances of MIDI::IO::SeqReader and MIDI::IO::SeqWriter are used
|
|
118
|
+
when a sequence reads itself from or writes itself to a MIDI file. You can
|
|
119
|
+
change that by setting a sequence's reader_class or writer_class attributes.
|
|
120
|
+
Instances of the classes contained in those attributes are created and used
|
|
121
|
+
whenever the sequence reads or writes itself.
|
|
122
|
+
|
|
123
|
+
=== MIDI::Track
|
|
124
|
+
|
|
125
|
+
A track contains an array of events.
|
|
126
|
+
|
|
127
|
+
When you modify the +events+ array, make sure to call recalc_times so each
|
|
128
|
+
event gets its +time_from_start+ recalculated. You don't have to do that
|
|
129
|
+
after every event you add; just remember to do so before using the track in a
|
|
130
|
+
way that expects the list of events to be ordered correctly.
|
|
131
|
+
|
|
132
|
+
A Track also holds a bit mask that specifies the channels used by the track.
|
|
133
|
+
This bit mask is set when the track is read from the MIDI file by a SeqReader
|
|
134
|
+
but is _not_ kept up to date by any other methods. Specifically, if you add
|
|
135
|
+
events to a track at any other time, the bit mask will not be updated.
|
|
136
|
+
|
|
137
|
+
=== MIDI::Event
|
|
138
|
+
|
|
139
|
+
Each event holds not only its delta time but also its time from the start of
|
|
140
|
+
the track. The track is responsible for recalculating its events' start times.
|
|
141
|
+
You can call MIDI::Track#recalc_times to do so.
|
|
142
|
+
|
|
143
|
+
Events have a number of boolean methods that identify their types, like
|
|
144
|
+
channel?, note?, note_on?, note_off?, meta?, system?, and realtime?.
|
|
145
|
+
|
|
146
|
+
Subclasses of MIDI::Event implement the various MIDI messages such as note on
|
|
147
|
+
and off, controller values, system exclusive data, and realtime bytes.
|
|
148
|
+
|
|
149
|
+
MIDI::Realtime events have delta values and start times, just like all the
|
|
150
|
+
other midilib event types do. (MIDI real time status bytes don't have delta
|
|
151
|
+
times, but this way we can record when in a track the realtime byte was
|
|
152
|
+
received and should be sent. This is useful for start/continue/stop events
|
|
153
|
+
that control other devices, for example.) Note that when a MIDI::Realtime
|
|
154
|
+
event is written out to a MIDI file, the delta time is not written.
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
== How To Use
|
|
158
|
+
|
|
159
|
+
The following examples show you how to use midilib to read, write, and
|
|
160
|
+
manipulate MIDI files and modify track events. See also the files in the
|
|
161
|
+
examples directory, which are described below.
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
=== Reading a MIDI File
|
|
165
|
+
|
|
166
|
+
To read a MIDI file, create a MIDI::Sequence object and call its #read method,
|
|
167
|
+
passing in an IO object.
|
|
168
|
+
|
|
169
|
+
The #read method takes an optional block. If present, the block is called once
|
|
170
|
+
after each track has finished being read. Each time, it is passed the total
|
|
171
|
+
number of tracks and the number of the current track that has just been read.
|
|
172
|
+
This is useful for notifying the user of progress, for example by updating a
|
|
173
|
+
GUI progress bar.
|
|
174
|
+
|
|
175
|
+
require 'midi/io/seqreader'
|
|
176
|
+
|
|
177
|
+
# Create a new, empty sequence.
|
|
178
|
+
seq = MIDI::Sequence.new()
|
|
179
|
+
|
|
180
|
+
# Read the contents of a MIDI file into the sequence.
|
|
181
|
+
File.open('my_midi_file.mid', 'rb') { | file |
|
|
182
|
+
seq.read(file) { | num_tracks, i |
|
|
183
|
+
# Print something when each track is read.
|
|
184
|
+
puts "read track #{i} of #{num_tracks}"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
=== Writing a MIDI File
|
|
190
|
+
|
|
191
|
+
To write a MIDI file, call the write method, passing in an IO object.
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
require 'midi/io/seqwriter'
|
|
195
|
+
|
|
196
|
+
# Start with a sequence that has something worth saving.
|
|
197
|
+
seq = read_or_create_seq_we_care_not_how()
|
|
198
|
+
|
|
199
|
+
# Write the sequence to a MIDI file.
|
|
200
|
+
File.open('my_output_file.mid', 'wb') { | file | seq.write(file) }
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
=== Editing a MIDI File
|
|
204
|
+
|
|
205
|
+
Combining the last two examples, here is a script that reads a MIDI file,
|
|
206
|
+
transposes some events, and writes the sequence out to a different file. This
|
|
207
|
+
is a useful template for programatically manipulating MIDI data.
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
This code transposes all of the note events (note on, note off, and poly
|
|
211
|
+
pressure) on channel 5 down one octave. It's easy to find events that need to
|
|
212
|
+
be transposed: the method #note? returns true.
|
|
213
|
+
|
|
214
|
+
==== Transposing One Channel
|
|
215
|
+
|
|
216
|
+
require 'midi/io/seqreader'
|
|
217
|
+
require 'midi/io/seqwriter'
|
|
218
|
+
|
|
219
|
+
# Create a new, empty sequence.
|
|
220
|
+
seq = MIDI::Sequence.new()
|
|
221
|
+
|
|
222
|
+
# Read the contents of a MIDI file into the sequence.
|
|
223
|
+
File.open('my_input_file.mid', 'rb') { | file |
|
|
224
|
+
seq.read(file) { | num_tracks, i |
|
|
225
|
+
# Print something when each track is read.
|
|
226
|
+
puts "read track #{i} of #{num_tracks}"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
# Iterate over every event in every track.
|
|
231
|
+
seq.each { | track |
|
|
232
|
+
track.each { | event |
|
|
233
|
+
# If the event is a note event (note on, note off, or poly
|
|
234
|
+
# pressure) and it is on MIDI channel 5 (channels start at
|
|
235
|
+
# 0, so we use 4), then transpose the event down one octave.
|
|
236
|
+
if event.note? && event.channel == 4
|
|
237
|
+
event.note -= 12
|
|
238
|
+
end
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
# Write the sequence to a MIDI file.
|
|
243
|
+
File.open('my_output_file.mid', 'wb') { | file | seq.write(file) }
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
=== Manipulating tracks
|
|
247
|
+
|
|
248
|
+
If you modify a track's list of events directly, don't forget to call
|
|
249
|
+
MIDI::Track#recalc_times when you are done.
|
|
250
|
+
|
|
251
|
+
track.events[42, 1] = array_of_events
|
|
252
|
+
track.events << an_event
|
|
253
|
+
track.merge(array_of_events)
|
|
254
|
+
track.recalc_times
|
|
255
|
+
|
|
256
|
+
=== Calculating delta times
|
|
257
|
+
|
|
258
|
+
A few methods in MIDI::Sequence make it easier to calculate the delta times
|
|
259
|
+
that represent note lengths. MIDI::Sequence#length_to_delta takes a note
|
|
260
|
+
length (a multiple of a quarter note) and returns the delta time given the
|
|
261
|
+
sequence's current ppqn (pulses per quarter note) setting. 1 is a quarter
|
|
262
|
+
note, 1.0/32.0 is a 32nd note (use floating-point numbers to avoid integer
|
|
263
|
+
rounding), 1.5 is a dotted quarter, etc. See the documentation for that method
|
|
264
|
+
for more information.
|
|
265
|
+
|
|
266
|
+
MIDI::Sequence::note_to_length takes a note name and returns a length value
|
|
267
|
+
(again, as a multiple of a quarter note). Legal note names are those found in
|
|
268
|
+
MIDI::Sequence::NOTE_TO_LENGTH, and may begin with "dotted" and/or end with
|
|
269
|
+
"triplet". For example, "whole", "sixteenth", "32nd", "quarter triplet",
|
|
270
|
+
"dotted 16th", and "dotted 8th triplet" are all legal note names.
|
|
271
|
+
|
|
272
|
+
Finally, MIDI::Sequence::note_to_delta takes a note name and returns a
|
|
273
|
+
delta time.
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
=== Example Scripts
|
|
277
|
+
|
|
278
|
+
Here are short descriptions of each of the examples found in the examples
|
|
279
|
+
directory.
|
|
280
|
+
|
|
281
|
+
* examples/from_scratch.rb shows you how to create a new sequence from scratch
|
|
282
|
+
and save it to a MIDI file. It creates a file called 'from_scratch.mid'.
|
|
283
|
+
|
|
284
|
+
* examples/seq2text.rb dumps a MIDI file as text. It reads in a sequence and
|
|
285
|
+
uses the to_s method of each event.
|
|
286
|
+
|
|
287
|
+
* examples/reader2text.rb dumps a MIDI file as text. It subclasses
|
|
288
|
+
MIDI::SeqReader instead of creating a sequence containing tracks and events.
|
|
289
|
+
|
|
290
|
+
* examples/transpose.rb transposes all note events (note on, note off, poly
|
|
291
|
+
pressure) on a specified channel by a specified amount.
|
|
292
|
+
|
|
293
|
+
* There is also one MIDI file, examples/NoFences.mid. It is a little pop ditty
|
|
294
|
+
I wrote. The instruments in this file use General MIDI patch numbers and
|
|
295
|
+
drum note assignments. Since I don't normally use GM patches, the sounds
|
|
296
|
+
used here are at best approximations of the sounds I use.
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
== Resources
|
|
300
|
+
|
|
301
|
+
The Ruby Web site (http://www.ruby-lang.org/en/index.html) contains an
|
|
302
|
+
introduction to Ruby, the Ruby Application Archive (RAA) at
|
|
303
|
+
http://raa.ruby-lang.org, and pointers to more information.
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
<em>Programming Ruby, The Pragmatic Programmer's Guide<em>, by David Thomas
|
|
307
|
+
and Andrew Hunt, is a well-written and practical introduction to Ruby. Its Web
|
|
308
|
+
page at http://www.rubycentral.com/book also contains a wealth of Ruby
|
|
309
|
+
information. Though the book is available online, I encourage you to purchase
|
|
310
|
+
a copy.
|
|
311
|
+
|
|
312
|
+
A description of the MIDI file format can be found in a few places such as
|
|
313
|
+
http://www.borg.com/~jglatt/tech/midifile.htm.
|
|
314
|
+
|
|
315
|
+
The MIDI message reference at http://www.io.com/~jimm/midi_ref.html describes
|
|
316
|
+
the format of MIDI commands.
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
= To Do
|
|
320
|
+
|
|
321
|
+
:include: TODO
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
= Support
|
|
325
|
+
|
|
326
|
+
* Visit the forums, bug list, and mailing list pages at
|
|
327
|
+
http://rubyforge.org/projects/midilib
|
|
328
|
+
|
|
329
|
+
* Send email to Jim Menard at mailto:jimm@io.com
|
|
330
|
+
|
|
331
|
+
* Ask on the ruby-talk mailing list
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
= Administrivia
|
|
335
|
+
|
|
336
|
+
Author:: Jim Menard (mailto:jimm@io.com)
|
|
337
|
+
Copyright:: Copyright (c) 2003-2004 Jim Menard
|
|
338
|
+
License:: Distributed under the same license as Ruby.
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
== Copying
|
|
342
|
+
|
|
343
|
+
midilib is copyrighted free software by Jim Menard and is released under the
|
|
344
|
+
same license as Ruby. See the Ruby license at
|
|
345
|
+
http://www.ruby-lang.org/en/LICENSE.txt.
|
|
346
|
+
|
|
347
|
+
midilib may be freely copied in its entirety providing this notice, all
|
|
348
|
+
source code, all documentation, and all other files are included.
|
|
349
|
+
|
|
350
|
+
midilib is Copyright (c) 2003-2004 by Jim Menard.
|
|
351
|
+
|
|
352
|
+
The song "No Fences" contained in the MIDI file examples/NoFences.mid is
|
|
353
|
+
Copyright (c) 1992 by Jim Menard (jimm@io.com). It may be freely used for
|
|
354
|
+
non-commercial purposes as long as the author is given credit.
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
== Warranty
|
|
358
|
+
|
|
359
|
+
This software is provided "as is" and without any express or implied
|
|
360
|
+
warranties, including, without limitation, the implied warranties of
|
|
361
|
+
merchantability and fitness for a particular purpose.
|