midi-message 0.0.1-i686-linux
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|