midi-message 0.0.1-i686-linux
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/LICENSE +13 -0
- data/README.rdoc +24 -0
- data/lib/midi-message/channel_message.rb +203 -0
- data/lib/midi-message/constant.rb +29 -0
- data/lib/midi-message/constants.rb +103 -0
- data/lib/midi-message/parser.rb +47 -0
- data/lib/midi-message/simple_message.rb +54 -0
- data/lib/midi-message/system_exclusive.rb +158 -0
- data/lib/midi-message/system_message.rb +43 -0
- data/lib/midi-message.rb +16 -0
- metadata +66 -0
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2010-2011 Ari Russo
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.rdoc
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
= midi-messages
|
2
|
+
|
3
|
+
== Summary
|
4
|
+
|
5
|
+
MIDI Messages in Ruby
|
6
|
+
|
7
|
+
== Features
|
8
|
+
|
9
|
+
* Objectification of the MIDI spec
|
10
|
+
* YAML Dictionary of MIDI constants
|
11
|
+
|
12
|
+
== Install
|
13
|
+
|
14
|
+
* gem install midi-message (*not yet available)
|
15
|
+
|
16
|
+
== Author
|
17
|
+
|
18
|
+
* {Ari Russo}[http://github.com/arirusso] <ari.russo at gmail.com>
|
19
|
+
|
20
|
+
== License
|
21
|
+
|
22
|
+
Apache 2.0, See the file LICENSE
|
23
|
+
|
24
|
+
Copyright (c) 2011 Ari Russo
|
@@ -0,0 +1,203 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module MIDIMessage
|
4
|
+
|
5
|
+
# common behavior amongst Channel Message types
|
6
|
+
module ChannelMessageBehavior
|
7
|
+
|
8
|
+
attr_reader :data,
|
9
|
+
:name,
|
10
|
+
:status
|
11
|
+
|
12
|
+
def initialize_channel_message(status_nibble_1, status_nibble_2, data_byte_1, data_byte_2 = 0)
|
13
|
+
@status = [status_nibble_1, status_nibble_2]
|
14
|
+
@data = [data_byte_1]
|
15
|
+
@data[1] = data_byte_2 if self.class::second_data_byte?
|
16
|
+
initialize_shortcuts
|
17
|
+
initialize_simple_message(status_nibble_1, status_nibble_2)
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_a
|
21
|
+
db2 = self.class::second_data_byte? ? @data[1] : nil
|
22
|
+
[@status[0] + @status[1], @data[0], db2].compact
|
23
|
+
end
|
24
|
+
alias_method :to_byte_array, :to_a
|
25
|
+
alias_method :to_bytes, :to_a
|
26
|
+
|
27
|
+
def to_hex_s
|
28
|
+
to_a.join
|
29
|
+
end
|
30
|
+
alias_method :hex, :to_hex_s
|
31
|
+
|
32
|
+
def initialize(*a)
|
33
|
+
initialize_channel_message(self.class::TypeId, *a)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.included(base)
|
37
|
+
base.extend(ClassMethods)
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
|
42
|
+
def type_for_status
|
43
|
+
0 + (const_get(:TypeId) << 4)
|
44
|
+
end
|
45
|
+
|
46
|
+
def type_id(id)
|
47
|
+
const_set(:TypeId, id)
|
48
|
+
end
|
49
|
+
|
50
|
+
def schema(*args)
|
51
|
+
self.send(:const_set, :Shortcuts, args)
|
52
|
+
const_set(:NumDataBytes, args.length-1)
|
53
|
+
end
|
54
|
+
alias_method :layout, :schema
|
55
|
+
|
56
|
+
def second_data_byte?
|
57
|
+
num = const_get(:NumDataBytes)
|
58
|
+
!num.nil? && num > 1
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize_shortcuts
|
64
|
+
props = [
|
65
|
+
{ :name => :status, :index => 1 },
|
66
|
+
{ :name => :data, :index => 0 },
|
67
|
+
{ :name => :data, :index => 1 }
|
68
|
+
]
|
69
|
+
shortcuts = self.class.send(:const_get, :Shortcuts)
|
70
|
+
shortcuts.each_with_index do |prop,i|
|
71
|
+
self.class.send(:attr_reader, prop)
|
72
|
+
self.class.send(:define_method, "#{prop}=") do |val|
|
73
|
+
send(:instance_variable_set, "@#{prop.to_s}", val)
|
74
|
+
send(props[i][:name])[props[i][:index]] = val
|
75
|
+
end
|
76
|
+
instance_variable_set("@#{prop}", send(props[i][:name])[props[i][:index]])
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
# use this if you want to instantiate a raw channel message
|
84
|
+
#
|
85
|
+
# example = ChannelMessage.new(0x9, 0x0, 0x40, 0x57) # creates a raw note-on message
|
86
|
+
#
|
87
|
+
class ChannelMessage
|
88
|
+
|
89
|
+
include SimpleMessageBehavior
|
90
|
+
include ChannelMessageBehavior
|
91
|
+
|
92
|
+
display_name 'Channel Message'
|
93
|
+
|
94
|
+
def initialize(*a)
|
95
|
+
initialize_channel_message(*a)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# MIDI Channel Aftertouch message
|
102
|
+
#
|
103
|
+
class ChannelAftertouch
|
104
|
+
|
105
|
+
include SimpleMessageBehavior
|
106
|
+
include ChannelMessageBehavior
|
107
|
+
|
108
|
+
schema :channel, :value
|
109
|
+
type_id 0xD
|
110
|
+
display_name 'Channel Aftertouch'
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# MIDI Control Change message
|
116
|
+
#
|
117
|
+
class ControlChange
|
118
|
+
|
119
|
+
include SimpleMessageBehavior
|
120
|
+
include ChannelMessageBehavior
|
121
|
+
|
122
|
+
schema :channel, :number, :value
|
123
|
+
type_id 0xB
|
124
|
+
display_name 'Control Change'
|
125
|
+
identifier :number
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# MIDI Note-Off message
|
131
|
+
#
|
132
|
+
class NoteOff
|
133
|
+
|
134
|
+
include SimpleMessageBehavior
|
135
|
+
include ChannelMessageBehavior
|
136
|
+
|
137
|
+
schema :channel, :note, :velocity
|
138
|
+
type_id 0x8
|
139
|
+
display_name 'Note Off'
|
140
|
+
use_constants 'Note'
|
141
|
+
identifier :note
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
#
|
146
|
+
# MIDI Note-On message
|
147
|
+
#
|
148
|
+
class NoteOn
|
149
|
+
|
150
|
+
include SimpleMessageBehavior
|
151
|
+
include ChannelMessageBehavior
|
152
|
+
|
153
|
+
schema :channel, :note, :velocity
|
154
|
+
type_id 0x9
|
155
|
+
display_name 'Note On'
|
156
|
+
use_constants 'Note'
|
157
|
+
identifier :note
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# MIDI Pitch Bend message
|
163
|
+
#
|
164
|
+
class PitchBend
|
165
|
+
|
166
|
+
include SimpleMessageBehavior
|
167
|
+
include ChannelMessageBehavior
|
168
|
+
|
169
|
+
schema :channel, :low, :high
|
170
|
+
type_id 0xE
|
171
|
+
DisplayName = 'Pitch Bend'
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
#
|
176
|
+
# MIDI Polyphonic (note specific) Aftertouch message
|
177
|
+
#
|
178
|
+
class PolyphonicAftertouch
|
179
|
+
|
180
|
+
include SimpleMessageBehavior
|
181
|
+
include ChannelMessageBehavior
|
182
|
+
|
183
|
+
schema :channel, :note, :value
|
184
|
+
type_id 0xA
|
185
|
+
DisplayName = 'Polyphonic Aftertouch'
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
# MIDI Program Change message
|
191
|
+
#
|
192
|
+
class ProgramChange
|
193
|
+
|
194
|
+
include SimpleMessageBehavior
|
195
|
+
include ChannelMessageBehavior
|
196
|
+
|
197
|
+
schema :channel, :program
|
198
|
+
type_id 0xC
|
199
|
+
DisplayName = 'Program Change'
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
require 'yaml'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
module MIDIMessage
|
7
|
+
|
8
|
+
# MIDI Constants
|
9
|
+
class Constant
|
10
|
+
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
# cache the constants data
|
15
|
+
require 'midi-message/constants'
|
16
|
+
@dict = YAML::load(@@data)
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](key)
|
20
|
+
@dict[key]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.[](key)
|
24
|
+
instance[key]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# better way to do this?
|
2
|
+
@@data = %q{
|
3
|
+
|
4
|
+
Control Change:
|
5
|
+
Bank Select: 0
|
6
|
+
Modulation Wheel: 1
|
7
|
+
Breath Controller: 2
|
8
|
+
Foot Controller: 4
|
9
|
+
Portamento Time: 5
|
10
|
+
Data Entry MSB: 6
|
11
|
+
Channel Volume: 7
|
12
|
+
Balance: 8
|
13
|
+
Pan: 10
|
14
|
+
Expression Controller: 11
|
15
|
+
General Purpose Controllers: 16
|
16
|
+
General Purpose Controllers: 17
|
17
|
+
General Purpose Controllers: 18
|
18
|
+
General Purpose Controllers: 19
|
19
|
+
LSB for controller 0: 32
|
20
|
+
LSB for controller 1: 33
|
21
|
+
LSB for controller 2: 34
|
22
|
+
LSB for controller 3: 35
|
23
|
+
LSB for controller 4: 36
|
24
|
+
LSB for controller 5: 37
|
25
|
+
LSB for controller 6: 38
|
26
|
+
LSB for controller 7: 39
|
27
|
+
LSB for controller 8: 40
|
28
|
+
LSB for controller 9: 41
|
29
|
+
LSB for controller 10: 42
|
30
|
+
LSB for controller 11: 43
|
31
|
+
LSB for controller 12: 44
|
32
|
+
LSB for controller 13: 45
|
33
|
+
LSB for controller 14: 46
|
34
|
+
LSB for controller 15: 47
|
35
|
+
LSB for controller 16: 48
|
36
|
+
LSB for controller 17: 49
|
37
|
+
LSB for controller 18: 50
|
38
|
+
LSB for controller 19: 51
|
39
|
+
LSB for controller 20: 52
|
40
|
+
LSB for controller 21: 53
|
41
|
+
LSB for controller 22: 54
|
42
|
+
LSB for controller 23: 55
|
43
|
+
LSB for controller 24: 56
|
44
|
+
LSB for controller 25: 57
|
45
|
+
LSB for controller 26: 58
|
46
|
+
LSB for controller 27: 59
|
47
|
+
LSB for controller 28: 60
|
48
|
+
LSB for controller 29: 61
|
49
|
+
LSB for controller 30: 62
|
50
|
+
LSB for controller 31: 63
|
51
|
+
Hold Pedal: 64
|
52
|
+
Portamento: 65
|
53
|
+
|
54
|
+
Control Mode:
|
55
|
+
All Sound Off: 120
|
56
|
+
All Controllers Off: 121
|
57
|
+
Local Keyboard Toggle: 122
|
58
|
+
All Notes Off: 123
|
59
|
+
Omni Mode Off: 124
|
60
|
+
Omni Mode On: 125
|
61
|
+
Mono: 126
|
62
|
+
Poly: 127
|
63
|
+
|
64
|
+
System Realtime:
|
65
|
+
Start: 0xFA
|
66
|
+
Clock: 0xF8
|
67
|
+
Continue: 0xFB
|
68
|
+
Stop: 0xFC
|
69
|
+
Reset: 0xFF
|
70
|
+
ActiveSense: 0xFE
|
71
|
+
|
72
|
+
Manufacturers:
|
73
|
+
|
74
|
+
SequentialCircuits: 1
|
75
|
+
BigBriar: 2
|
76
|
+
Octave: 3
|
77
|
+
Moog: 4
|
78
|
+
Passport: 5
|
79
|
+
Lexicon: 6
|
80
|
+
|
81
|
+
PAIA: 0x11
|
82
|
+
Simmons: 0x12
|
83
|
+
GentleElectric: 0x13
|
84
|
+
Fairlight: 0x14
|
85
|
+
BonTempi: 0x20
|
86
|
+
SIEL: 0x21
|
87
|
+
SyntheAxe: 0x23
|
88
|
+
|
89
|
+
Kawai: 0x40
|
90
|
+
Roland: 0x41
|
91
|
+
Korg: 0x42
|
92
|
+
Yamaha: 0x43
|
93
|
+
Casio: 0x44
|
94
|
+
Akai: 0x47
|
95
|
+
|
96
|
+
Emagic: [0x00, 0x20, 0x31]
|
97
|
+
Behringer: [0x00, 0x20, 0x32]
|
98
|
+
|
99
|
+
Note:
|
100
|
+
|
101
|
+
C3: 64
|
102
|
+
|
103
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module MIDIMessage
|
4
|
+
|
5
|
+
# very simple parsing
|
6
|
+
# for more advanced parsing check out {nibbler}[http://github.com/arirusso/nibbler]
|
7
|
+
class Parser
|
8
|
+
|
9
|
+
# can take either a hex string eg Parser.new("904040")
|
10
|
+
# or bytes eg Parser.new(0x90, 0x40, 0x40)
|
11
|
+
# or an array of bytes eg Parser.new([0x90, 0x40, 0x40])
|
12
|
+
def initialize(*a)
|
13
|
+
@data = case a.first
|
14
|
+
when Array then a.first
|
15
|
+
when Numeric then a
|
16
|
+
when String then str_to_bytes(a.first)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse
|
21
|
+
first_nibble = @data.first >> 4
|
22
|
+
second_nibble = @data.first >> 8
|
23
|
+
case first_nibble
|
24
|
+
when 0x8 then NoteOff.new(second_nibble, @data[1], @data[2])
|
25
|
+
when 0x9 then NoteOn.new(second_nibble, @data[1], @data[2])
|
26
|
+
when 0xA then PolyphonicAftertouch.new(second_nibble, @data[1], @data[2])
|
27
|
+
when 0xB then ControlChange.new(second_nibble, @data[1], @data[2])
|
28
|
+
when 0xC then ProgramChange.new(second_nibble, @data[1])
|
29
|
+
when 0xD then ChannelAftertouch.new(second_nibble, @data[1])
|
30
|
+
when 0xE then PitchBend.new(second_nibble, @data[1], @data[2])
|
31
|
+
when 0xF then case second_nibble
|
32
|
+
when 0x0 then SystemExclusive.new(*@data)
|
33
|
+
when 0x1..0x6 then SystemCommon.new(second_nibble, @data[1], @data[2])
|
34
|
+
when 0x8..0xF then SystemRealtime.new(second_nibble)
|
35
|
+
else nil
|
36
|
+
end
|
37
|
+
else nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.parse(*a)
|
44
|
+
Parser.new(*a).parse
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module MIDIMessage
|
4
|
+
|
5
|
+
# common behavior amongst all Message types
|
6
|
+
module SimpleMessageBehavior
|
7
|
+
|
8
|
+
attr_reader :name,
|
9
|
+
:status,
|
10
|
+
:verbose_name
|
11
|
+
|
12
|
+
def initialize_simple_message(status_nibble_1, status_nibble_2)
|
13
|
+
@status = [status_nibble_1, status_nibble_2]
|
14
|
+
group_name = self.class.const_get(:DisplayName)
|
15
|
+
group_name_alias = self.class.const_get(:UseConstants) rescue nil
|
16
|
+
val = self.send(self.class.const_get(:Identifier)) rescue @status[1]
|
17
|
+
group = Constant[group_name] || (group_name_alias.nil? ? nil : Constant[group_name_alias])
|
18
|
+
unless group.nil?
|
19
|
+
const = group.find { |k,v| k if v.eql?(val) }
|
20
|
+
unless const.nil?
|
21
|
+
@name = const.first
|
22
|
+
@verbose_name = "#{self.class::DisplayName}: #{const.first}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_hex_s
|
28
|
+
to_a.join
|
29
|
+
end
|
30
|
+
alias_method :hex, :to_hex_s
|
31
|
+
|
32
|
+
def self.included(base)
|
33
|
+
base.extend(ClassMethods)
|
34
|
+
end
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
|
38
|
+
def display_name(name)
|
39
|
+
const_set(:DisplayName, name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def use_constants(name)
|
43
|
+
const_set(:UseConstants, name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def identifier(name)
|
47
|
+
const_set(:Identifier, name)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
#
|
4
|
+
module MIDIMessage
|
5
|
+
|
6
|
+
module SystemExclusive
|
7
|
+
|
8
|
+
# convert raw MIDI data to SysEx message objects
|
9
|
+
def self.new(*bytes)
|
10
|
+
|
11
|
+
start_status = bytes.shift
|
12
|
+
end_status = bytes.pop
|
13
|
+
|
14
|
+
return nil unless start_status.eql?(0xF0) && end_status.eql?(0xF7)
|
15
|
+
|
16
|
+
fixed_length_message_part = bytes.slice!(0,7)
|
17
|
+
|
18
|
+
manufacturer_id = fixed_length_message_part[0]
|
19
|
+
device_id = fixed_length_message_part[1]
|
20
|
+
model_id = fixed_length_message_part[2]
|
21
|
+
|
22
|
+
msg_class = case fixed_length_message_part[3]
|
23
|
+
when 0x11 then Request
|
24
|
+
when 0x12 then Command
|
25
|
+
end
|
26
|
+
|
27
|
+
address = fixed_length_message_part.slice(4,3)
|
28
|
+
checksum = bytes.slice!((bytes.length - 1), 1)
|
29
|
+
value = bytes
|
30
|
+
|
31
|
+
node = Node.new(manufacturer_id, model_id, :device_id => device_id)
|
32
|
+
msg_class.new(address, value, :checksum => checksum, :node => node)
|
33
|
+
end
|
34
|
+
|
35
|
+
# basic SysEx data that a message class will contain
|
36
|
+
module Data
|
37
|
+
|
38
|
+
attr_reader :address,
|
39
|
+
:checksum,
|
40
|
+
:device
|
41
|
+
|
42
|
+
StartByte = 0xF0
|
43
|
+
EndByte = 0xF7
|
44
|
+
|
45
|
+
# an array of message parts. multiple byte parts will be represented as an array of bytes
|
46
|
+
def to_a
|
47
|
+
array
|
48
|
+
end
|
49
|
+
|
50
|
+
# a flat array of message bytes
|
51
|
+
def to_byte_array
|
52
|
+
array.flatten
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def address_to_i
|
58
|
+
address.inject { |a,b| a + b }
|
59
|
+
end
|
60
|
+
|
61
|
+
def value_to_i
|
62
|
+
value.kind_of?(Array) ? value.inject { |a,b| a + b } : value
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize_sysex(address, options = {})
|
66
|
+
@node = options[:node]
|
67
|
+
@checksum = options[:checksum]
|
68
|
+
@address = address
|
69
|
+
end
|
70
|
+
|
71
|
+
def array
|
72
|
+
# this may need to be cached when properties are updated
|
73
|
+
# might be worth benchmarking
|
74
|
+
@checksum = (128 - (address_to_i + value_to_i).divmod(128)[1])
|
75
|
+
[
|
76
|
+
StartByte,
|
77
|
+
@node.manufacturer,
|
78
|
+
(@device_id || @node.device_id),
|
79
|
+
@node.model_id,
|
80
|
+
status_byte,
|
81
|
+
address,
|
82
|
+
value,
|
83
|
+
@checksum,
|
84
|
+
EndByte
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# A SysEx command message
|
91
|
+
#
|
92
|
+
class Command
|
93
|
+
|
94
|
+
include Data
|
95
|
+
|
96
|
+
attr_reader :data
|
97
|
+
|
98
|
+
StatusByte = 0x12
|
99
|
+
|
100
|
+
def initialize(address, data, options = {})
|
101
|
+
@data = data
|
102
|
+
initialize_sysex(address, options)
|
103
|
+
end
|
104
|
+
|
105
|
+
def value
|
106
|
+
@data
|
107
|
+
end
|
108
|
+
|
109
|
+
def data=(val)
|
110
|
+
@data = val
|
111
|
+
update_byte_array
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# The SystemExclusive::Node represents a hardware synthesizer or other MIDI device that a message
|
118
|
+
# is being sent to or received from.
|
119
|
+
#
|
120
|
+
class Node
|
121
|
+
|
122
|
+
attr_accessor :device_id # (Not to be confused with any kind of Device class in this library)
|
123
|
+
attr_reader :manufacturer, :model_id
|
124
|
+
|
125
|
+
def initialize(manufacturer, model_id, options = {})
|
126
|
+
@device_id = options[:device_id]
|
127
|
+
@model_id = model_id
|
128
|
+
@manufacturer = manufacturer
|
129
|
+
end
|
130
|
+
|
131
|
+
def message(*a)
|
132
|
+
a << { :node => self }
|
133
|
+
Command.new(*a)
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
# A SysEx request message
|
139
|
+
#
|
140
|
+
class Request
|
141
|
+
|
142
|
+
include Data
|
143
|
+
|
144
|
+
attr_accessor :size
|
145
|
+
alias_method :value, :size
|
146
|
+
|
147
|
+
StatusByte = 0x11
|
148
|
+
|
149
|
+
def initialize(address, size, options = {})
|
150
|
+
@size = size
|
151
|
+
initialize_sysex(address, options = {})
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
module MIDIMessage
|
4
|
+
|
5
|
+
#
|
6
|
+
# MIDI System-Common message
|
7
|
+
#
|
8
|
+
class SystemCommon
|
9
|
+
|
10
|
+
include SimpleMessageBehavior
|
11
|
+
display_name 'System Common'
|
12
|
+
|
13
|
+
attr_reader :status,
|
14
|
+
:data
|
15
|
+
|
16
|
+
def initialize(status_nibble_2, data_byte_1 = nil, data_byte_2 = nil)
|
17
|
+
@data = [data_byte_1, data_byte_2]
|
18
|
+
initialize_simple_message(0xF, status_nibble_2)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# MIDI System-Realtime message
|
25
|
+
#
|
26
|
+
class SystemRealtime
|
27
|
+
|
28
|
+
include SimpleMessageBehavior
|
29
|
+
display_name 'System Realtime'
|
30
|
+
|
31
|
+
attr_reader :status
|
32
|
+
|
33
|
+
def initialize(id)
|
34
|
+
initialize_simple_message(0xF, id)
|
35
|
+
end
|
36
|
+
|
37
|
+
def id
|
38
|
+
@status[1]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/midi-message.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# MIDI Messages in Ruby
|
4
|
+
#
|
5
|
+
module MIDIMessage
|
6
|
+
|
7
|
+
VERSION = "0.0.1"
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'midi-message/simple_message'
|
12
|
+
require 'midi-message/channel_message'
|
13
|
+
require 'midi-message/constant'
|
14
|
+
require 'midi-message/parser'
|
15
|
+
require 'midi-message/system_message'
|
16
|
+
require 'midi-message/system_exclusive'
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midi-message
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: i686-linux
|
7
|
+
authors:
|
8
|
+
- Ari Russo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-29 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: MIDI Messages, objectified in Ruby.
|
18
|
+
email:
|
19
|
+
- ari.russo@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- lib/midi-message.rb
|
28
|
+
- lib/midi-message/system_exclusive.rb
|
29
|
+
- lib/midi-message/channel_message.rb
|
30
|
+
- lib/midi-message/simple_message.rb
|
31
|
+
- lib/midi-message/constants.rb
|
32
|
+
- lib/midi-message/parser.rb
|
33
|
+
- lib/midi-message/system_message.rb
|
34
|
+
- lib/midi-message/constant.rb
|
35
|
+
- LICENSE
|
36
|
+
- README.rdoc
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/arirusso/midi-message
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 1.3.6
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project: midi-message
|
61
|
+
rubygems_version: 1.6.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: MIDI Messages in Ruby.
|
65
|
+
test_files: []
|
66
|
+
|