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
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
require 'midilib/consts'
|
|
2
|
+
require 'midilib/utils'
|
|
3
|
+
|
|
4
|
+
module MIDI
|
|
5
|
+
|
|
6
|
+
# The abstract superclass of all MIDI events.
|
|
7
|
+
class Event
|
|
8
|
+
# Modifying delta_time does not affect time_from_start. You need to call
|
|
9
|
+
# the event's track's +recalc_time+ method.
|
|
10
|
+
attr_accessor :delta_time
|
|
11
|
+
# The start time of this event from the beginning of the track. This value
|
|
12
|
+
# is held here but is maintained by the track.
|
|
13
|
+
attr_accessor :time_from_start
|
|
14
|
+
# The MIDI status byte. Never includes the channel, which is held
|
|
15
|
+
# separately by MIDI::ChannelEvent.
|
|
16
|
+
attr_reader :status
|
|
17
|
+
|
|
18
|
+
# Determines if to_s outputs hex note numbers (false, the default) or
|
|
19
|
+
# decimal note names (true).
|
|
20
|
+
attr_accessor :print_note_names
|
|
21
|
+
|
|
22
|
+
# Determines if to_s outputs numbers as hex (false, the default) or
|
|
23
|
+
# decimal # (true). Delta times are always printed as decimal.
|
|
24
|
+
attr_accessor :print_decimal_numbers
|
|
25
|
+
|
|
26
|
+
def initialize(status = 0, delta_time = 0)
|
|
27
|
+
@status = status
|
|
28
|
+
@delta_time = delta_time
|
|
29
|
+
@is_channel = false # the majority of events are channel events
|
|
30
|
+
@is_note = false # note on, note off, and poly press return true
|
|
31
|
+
@is_note_on = false
|
|
32
|
+
@is_note_off = false
|
|
33
|
+
@is_meta = false
|
|
34
|
+
@is_system = false
|
|
35
|
+
@is_realtime = false
|
|
36
|
+
@time_from_start = 0 # maintained by tracks
|
|
37
|
+
end
|
|
38
|
+
protected :initialize
|
|
39
|
+
|
|
40
|
+
# Returns the raw bytes that are written to a MIDI file or output to a
|
|
41
|
+
# MIDI stream. In MIDI::EVENT this raises a "subclass responsibility"
|
|
42
|
+
# exception.
|
|
43
|
+
def data_as_bytes
|
|
44
|
+
raise "subclass responsibility"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns +true+ if this is a channel event.
|
|
48
|
+
def channel?
|
|
49
|
+
return @is_channel
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns +true+ if this is a note on, note off, or polyphonic pressure
|
|
53
|
+
# event.
|
|
54
|
+
def note?
|
|
55
|
+
return @is_note
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns +true+ if this is a note on event.
|
|
59
|
+
def note_on?
|
|
60
|
+
@is_note_on
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns +true+ if this is a note off event.
|
|
64
|
+
def note_off?
|
|
65
|
+
@is_note_off
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Returns +true+ if this is a meta event.
|
|
69
|
+
def meta?
|
|
70
|
+
return @is_meta
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Returns +true+ if this is a system message event.
|
|
74
|
+
def system?
|
|
75
|
+
return @is_system
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns +true+ if this is a realtime status byte.
|
|
79
|
+
|
|
80
|
+
def realtime?
|
|
81
|
+
return @is_realtime
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Quantize this event's time_from_start by moving it to the nearest
|
|
85
|
+
# multiple of +boundary+. See MIDI::Track#quantize. *Note*: does not
|
|
86
|
+
# modify the event's delta_time, though MIDI::Track#quantize calls
|
|
87
|
+
# recalc_delta_from_times after it asks each event to quantize itself.
|
|
88
|
+
def quantize_to(boundary)
|
|
89
|
+
diff = @time_from_start % boundary
|
|
90
|
+
@time_from_start -= diff
|
|
91
|
+
if diff >= boundary / 2
|
|
92
|
+
@time_from_start += boundary
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# For sorting. Uses @time_from_start, which is maintained by this event's
|
|
97
|
+
# track. I'm not sure this is necessary, since each track has to
|
|
98
|
+
# maintain its events' time-from-start values anyway.
|
|
99
|
+
def <=>(an_event)
|
|
100
|
+
return @time_from_start <=> an_event.time_from_start
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns +val+ as a decimal or hex string, depending upon the value of
|
|
104
|
+
# @print_decimal_numbers.
|
|
105
|
+
def number_to_s(val)
|
|
106
|
+
return @print_decimal_numbers ? val.to_s : ('%02x' % val)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def to_s
|
|
110
|
+
"#{@delta_time}: "
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# The abstract superclass of all channel events (events that have a MIDI
|
|
115
|
+
# channel, like notes and program changes).
|
|
116
|
+
class ChannelEvent < Event
|
|
117
|
+
# MIDI channel, 0-15.
|
|
118
|
+
attr_accessor :channel
|
|
119
|
+
|
|
120
|
+
def initialize(status, channel, delta_time)
|
|
121
|
+
super(status, delta_time)
|
|
122
|
+
@channel = channel
|
|
123
|
+
@is_channel = true
|
|
124
|
+
end
|
|
125
|
+
protected :initialize
|
|
126
|
+
|
|
127
|
+
def to_s
|
|
128
|
+
return super << "ch #{number_to_s(@channel)} "
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# The abstract superclass of all note on, and note off, and polyphonic
|
|
134
|
+
# pressure events.
|
|
135
|
+
class NoteEvent < ChannelEvent
|
|
136
|
+
attr_accessor :note, :velocity
|
|
137
|
+
def initialize(status, channel, note, velocity, delta_time)
|
|
138
|
+
super(status, channel, delta_time)
|
|
139
|
+
@note = note
|
|
140
|
+
@velocity = velocity
|
|
141
|
+
@is_note = true
|
|
142
|
+
end
|
|
143
|
+
protected :initialize
|
|
144
|
+
|
|
145
|
+
PITCHES = %w(C C# D D# E F F# G G# A A# B)
|
|
146
|
+
|
|
147
|
+
# Returns note name as a pitch/octave string like "C4" or "F#6".
|
|
148
|
+
def pch_oct(val=@note)
|
|
149
|
+
pch = val % 12
|
|
150
|
+
oct = (val / 12) - 1
|
|
151
|
+
"#{PITCHES[pch]}#{oct}"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# If @print_note_names is true, returns pch_oct(val) else returns value
|
|
155
|
+
# as a number using number_to_s.
|
|
156
|
+
def note_to_s
|
|
157
|
+
return @print_note_names ? pch_oct(@note) : number_to_s(@note)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def data_as_bytes
|
|
161
|
+
data = ''
|
|
162
|
+
data << (@status + @channel)
|
|
163
|
+
data << @note
|
|
164
|
+
data << @velocity
|
|
165
|
+
return data
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
class NoteOnEvent < NoteEvent
|
|
170
|
+
attr_accessor :off
|
|
171
|
+
def initialize(channel = 0, note = 64, velocity = 64, delta_time = 0)
|
|
172
|
+
super(NOTE_ON, channel, note, velocity, delta_time)
|
|
173
|
+
@is_note_on = true
|
|
174
|
+
end
|
|
175
|
+
def to_s
|
|
176
|
+
return super <<
|
|
177
|
+
"on #{note_to_s} #{number_to_s(@velocity)}"
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class NoteOffEvent < NoteEvent
|
|
182
|
+
attr_accessor :on
|
|
183
|
+
def initialize(channel = 0, note = 64, velocity = 64, delta_time = 0)
|
|
184
|
+
super(NOTE_OFF, channel, note, velocity, delta_time)
|
|
185
|
+
@is_note_off = true
|
|
186
|
+
end
|
|
187
|
+
def to_s
|
|
188
|
+
return super <<
|
|
189
|
+
"off #{note_to_s} #{number_to_s(@velocity)}"
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
class PolyPressure < NoteEvent
|
|
194
|
+
def initialize(channel = 0, note = 64, value = 0, delta_time = 0)
|
|
195
|
+
super(POLY_PRESSSURE, channel, note, value, delta_time)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def pressure
|
|
199
|
+
return @velocity
|
|
200
|
+
end
|
|
201
|
+
def pressure=(val)
|
|
202
|
+
@velocity = val
|
|
203
|
+
end
|
|
204
|
+
def to_s
|
|
205
|
+
return super <<
|
|
206
|
+
"poly press #{number_to_s(@channel)} #{note_to_s} #{number_to_s(@velocity)}"
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
class Controller < ChannelEvent
|
|
211
|
+
attr_accessor :controller, :value
|
|
212
|
+
|
|
213
|
+
def initialize(channel = 0, controller = 0, value = 0, delta_time = 0)
|
|
214
|
+
super(CONTROLLER, channel, delta_time)
|
|
215
|
+
@controller = controller
|
|
216
|
+
@value = value
|
|
217
|
+
@is_controller = true
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def data_as_bytes
|
|
221
|
+
data = ''
|
|
222
|
+
data << (@status + @channel)
|
|
223
|
+
data << @controller
|
|
224
|
+
data << @value
|
|
225
|
+
return data
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def to_s
|
|
229
|
+
return super << "cntl #{number_to_s(@controller)} #{number_to_s(@value)}"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
class ProgramChange < ChannelEvent
|
|
234
|
+
attr_accessor :program
|
|
235
|
+
|
|
236
|
+
def initialize(channel = 0, program = 0, delta_time = 0)
|
|
237
|
+
super(PROGRAM_CHANGE, channel, delta_time)
|
|
238
|
+
@program = program
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def data_as_bytes
|
|
242
|
+
data = ''
|
|
243
|
+
data << (@status + @channel)
|
|
244
|
+
data << @program
|
|
245
|
+
return data
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def to_s
|
|
249
|
+
return super << "prog #{number_to_s(@program)}"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
class ChannelPressure < ChannelEvent
|
|
254
|
+
attr_accessor :pressure
|
|
255
|
+
|
|
256
|
+
def initialize(channel = 0, pressure = 0, delta_time = 0)
|
|
257
|
+
super(CHANNEL_PRESSURE, channel, delta_time)
|
|
258
|
+
@pressure = pressure
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def data_as_bytes
|
|
262
|
+
data = ''
|
|
263
|
+
data << (@status + @channel)
|
|
264
|
+
data << @pressure
|
|
265
|
+
return data
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def to_s
|
|
269
|
+
return super << "chan press #{number_to_s(@pressure)}"
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
class PitchBend < ChannelEvent
|
|
274
|
+
attr_accessor :value
|
|
275
|
+
|
|
276
|
+
def initialize(channel = 0, value = 0, delta_time = 0)
|
|
277
|
+
super(PITCH_BEND, channel, delta_time)
|
|
278
|
+
@value = value
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def data_as_bytes
|
|
282
|
+
data = ''
|
|
283
|
+
data << (@status + @channel)
|
|
284
|
+
data << ((@value >> 8) & 0xff) # msb
|
|
285
|
+
data << (@value & 0xff) # lsb
|
|
286
|
+
return data
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def to_s
|
|
290
|
+
return super << "pb #{number_to_s(@value)}"
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
class SystemCommon < Event
|
|
295
|
+
def initialize(status, delta_time)
|
|
296
|
+
super(status, delta_time)
|
|
297
|
+
@is_system = true
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
class SystemExclusive < SystemCommon
|
|
302
|
+
attr_accessor :data
|
|
303
|
+
|
|
304
|
+
def initialize(data, delta_time = 0)
|
|
305
|
+
super(SYSEX, delta_time)
|
|
306
|
+
@data = data
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def data_as_bytes
|
|
310
|
+
data = ''
|
|
311
|
+
data << @status
|
|
312
|
+
data << Utils.as_var_len(@data.length)
|
|
313
|
+
data << @data
|
|
314
|
+
data << EOX
|
|
315
|
+
return data
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def to_s
|
|
319
|
+
return super << "sys ex"
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
class SongPointer < SystemCommon
|
|
324
|
+
attr_accessor :pointer
|
|
325
|
+
|
|
326
|
+
def initialize(pointer = 0, delta_time = 0)
|
|
327
|
+
super(SONG_POINTER, delta_time)
|
|
328
|
+
@pointer = pointer
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def data_as_bytes
|
|
332
|
+
data = ''
|
|
333
|
+
data << @status
|
|
334
|
+
data << ((@pointer >> 8) & 0xff)
|
|
335
|
+
data << (@pointer & 0xff)
|
|
336
|
+
return data
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def to_s
|
|
340
|
+
return super << "song ptr #{number_to_s(@pointer)}"
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
class SongSelect < SystemCommon
|
|
345
|
+
attr_accessor :song
|
|
346
|
+
|
|
347
|
+
def initialize(song = 0, delta_time = 0)
|
|
348
|
+
super(SONG_SELECT, delta_time)
|
|
349
|
+
@song = song
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def data_as_bytes
|
|
353
|
+
data = ''
|
|
354
|
+
data << @status
|
|
355
|
+
data << @song
|
|
356
|
+
return data
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def to_s
|
|
360
|
+
return super << "song sel #{number_to_s(@song)}"
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
class TuneRequest < SystemCommon
|
|
365
|
+
def initialize(delta_time = 0)
|
|
366
|
+
super(TUNE_REQUEST, delta_time)
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def data_as_bytes
|
|
370
|
+
data = ''
|
|
371
|
+
data << @status
|
|
372
|
+
return data
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def to_s
|
|
376
|
+
return super << "tune req"
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
class Realtime < Event
|
|
381
|
+
def initialize(status, delta_time)
|
|
382
|
+
super(status, delta_time)
|
|
383
|
+
@is_realtime = true
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def data_as_bytes
|
|
387
|
+
data = ''
|
|
388
|
+
data << @status
|
|
389
|
+
return data
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def to_s
|
|
393
|
+
return super << "realtime #{number_to_s(@status)}"
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
class Clock < Realtime
|
|
398
|
+
def initialize(delta_time = 0)
|
|
399
|
+
super(CLOCK, delta_time)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def to_s
|
|
403
|
+
return super << "clock"
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
class Start < Realtime
|
|
408
|
+
def initialize(delta_time = 0)
|
|
409
|
+
super(START, delta_time)
|
|
410
|
+
end
|
|
411
|
+
def to_s
|
|
412
|
+
return super << "start"
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
class Continue < Realtime
|
|
417
|
+
def initialize(delta_time = 0)
|
|
418
|
+
super(CONTINUE, delta_time)
|
|
419
|
+
end
|
|
420
|
+
def to_s
|
|
421
|
+
return super << "continue"
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
class Stop < Realtime
|
|
426
|
+
def initialize(delta_time = 0)
|
|
427
|
+
super(STOP, delta_time)
|
|
428
|
+
end
|
|
429
|
+
def to_s
|
|
430
|
+
return super << "stop"
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
class ActiveSense < Realtime
|
|
435
|
+
def initialize(delta_time = 0)
|
|
436
|
+
super(ACTIVE_SENSE, delta_time)
|
|
437
|
+
end
|
|
438
|
+
def to_s
|
|
439
|
+
return super << "act sens"
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
class SystemReset < Realtime
|
|
444
|
+
def initialize(delta_time = 0)
|
|
445
|
+
super(SYSTEM_RESET, delta_time)
|
|
446
|
+
end
|
|
447
|
+
def to_s
|
|
448
|
+
return super << "sys reset"
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
class MetaEvent < Event
|
|
453
|
+
attr_reader :meta_type
|
|
454
|
+
attr_accessor :data
|
|
455
|
+
|
|
456
|
+
def initialize(meta_type, data = nil, delta_time = 0)
|
|
457
|
+
super(META_EVENT, delta_time)
|
|
458
|
+
@meta_type = meta_type
|
|
459
|
+
@data = data
|
|
460
|
+
@is_meta = true
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def data_as_bytes
|
|
464
|
+
data = ''
|
|
465
|
+
data << @status
|
|
466
|
+
data << @meta_type
|
|
467
|
+
data << (@data ? Utils.as_var_len(@data.length) : 0)
|
|
468
|
+
data << @data if @data
|
|
469
|
+
return data
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
def to_s
|
|
473
|
+
str = super()
|
|
474
|
+
str << "meta #{number_to_s(@meta_type)} "
|
|
475
|
+
# I know, I know...this isn't OO.
|
|
476
|
+
case @meta_type
|
|
477
|
+
when META_SEQ_NUM
|
|
478
|
+
str << "sequence number"
|
|
479
|
+
when META_TEXT
|
|
480
|
+
str << "text: #{@data}"
|
|
481
|
+
when META_COPYRIGHT
|
|
482
|
+
str << "copyright: #{@data}"
|
|
483
|
+
when META_SEQ_NAME
|
|
484
|
+
str << "sequence or track name: #{@data}"
|
|
485
|
+
when META_INSTRUMENT
|
|
486
|
+
str << "instrument name: #{@data}"
|
|
487
|
+
when META_LYRIC
|
|
488
|
+
str << "lyric: #{@data}"
|
|
489
|
+
when META_MARKER
|
|
490
|
+
str << "marker: #{@data}"
|
|
491
|
+
when META_CUE
|
|
492
|
+
str << "cue point: #{@data}"
|
|
493
|
+
when META_TRACK_END
|
|
494
|
+
str << "track end"
|
|
495
|
+
# when META_SET_TEMPO
|
|
496
|
+
# str << "set tempo: #{@data}"
|
|
497
|
+
when META_SMPTE
|
|
498
|
+
str << "smpte"
|
|
499
|
+
when META_TIME_SIG
|
|
500
|
+
str << "time signature"
|
|
501
|
+
when META_KEY_SIG
|
|
502
|
+
str << "key signature"
|
|
503
|
+
when META_SEQ_SPECIF
|
|
504
|
+
str << "sequence specific"
|
|
505
|
+
else
|
|
506
|
+
str << "(other)"
|
|
507
|
+
end
|
|
508
|
+
return str
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
class Marker < MetaEvent
|
|
513
|
+
def initialize(msg, delta_time = 0)
|
|
514
|
+
super(META_MARKER, msg, delta_time)
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
class Tempo < MetaEvent
|
|
519
|
+
|
|
520
|
+
MICROSECS_PER_MINUTE = 1_000_000 * 60
|
|
521
|
+
|
|
522
|
+
# Translates beats per minute to microseconds per quarter note (beat).
|
|
523
|
+
def Tempo.bpm_to_mpq(bpm)
|
|
524
|
+
return MICROSECS_PER_MINUTE / bpm
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# Translates microseconds per quarter note (beat) to beats per minute.
|
|
528
|
+
def Tempo.mpq_to_bpm(mpq)
|
|
529
|
+
return MICROSECS_PER_MINUTE / mpq
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
def initialize(msecs_per_qnote, delta_time = 0)
|
|
533
|
+
super(META_SET_TEMPO, msecs_per_qnote, delta_time)
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
def tempo
|
|
537
|
+
return @data
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def tempo=(val)
|
|
541
|
+
@data = val
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def data_as_bytes
|
|
545
|
+
data = ''
|
|
546
|
+
data << @status
|
|
547
|
+
data << @meta_type
|
|
548
|
+
data << 3
|
|
549
|
+
data << ((@data >> 16) & 0xff)
|
|
550
|
+
data << ((@data >> 8) & 0xff)
|
|
551
|
+
data << (@data & 0xff)
|
|
552
|
+
return data
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def to_s
|
|
556
|
+
"tempo #{@data} msecs per qnote (#{Tempo.mpq_to_bpm(@data)} bpm)"
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
end
|