unimidi 0.1.14-i386-mingw32 → 0.2.0-i386-mingw32
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 +12 -12
- data/README.rdoc +82 -63
- data/bin/unimidi +9 -9
- data/lib/unimidi.rb +31 -31
- data/lib/unimidi/adapter/alsa-rawmidi.rb +25 -25
- data/lib/unimidi/adapter/ffi-coremidi.rb +25 -25
- data/lib/unimidi/adapter/midi-jruby.rb +25 -25
- data/lib/unimidi/adapter/midi-winmm.rb +25 -25
- data/lib/unimidi/congruous_api_adapter.rb +226 -214
- data/lib/unimidi/platform.rb +35 -35
- data/lib/unimidi/type_conversion.rb +14 -14
- data/test/config.rb +15 -0
- data/test/helper.rb +72 -0
- data/test/test_input_buffer.rb +44 -0
- data/test/test_io.rb +117 -0
- data/test/test_platform.rb +35 -0
- metadata +45 -33
@@ -1,215 +1,227 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
|
4
|
-
module UniMIDI
|
5
|
-
|
6
|
-
module CongruousApiAdapter
|
7
|
-
|
8
|
-
module Device
|
9
|
-
|
10
|
-
def initialize(device_obj)
|
11
|
-
@device = device_obj
|
12
|
-
@id = @device.id
|
13
|
-
@name = @device.name
|
14
|
-
@type = @device.type
|
15
|
-
end
|
16
|
-
|
17
|
-
# enable the device for use, can be passed a block to which the device will be passed back
|
18
|
-
def open(*a, &block)
|
19
|
-
@device.open(*a)
|
20
|
-
unless block.nil?
|
21
|
-
begin
|
22
|
-
yield(self)
|
23
|
-
ensure
|
24
|
-
close
|
25
|
-
end
|
26
|
-
else
|
27
|
-
self
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# close the device
|
32
|
-
def close(*a)
|
33
|
-
@device.close(*a)
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.included(base)
|
37
|
-
base.send(:attr_reader, :name)
|
38
|
-
base.send(:attr_reader, :id)
|
39
|
-
base.send(:attr_reader, :type)
|
40
|
-
end
|
41
|
-
|
42
|
-
module ClassMethods
|
43
|
-
|
44
|
-
# returns the first device for this class
|
45
|
-
def first(*a)
|
46
|
-
dev = @deference[self].first(*a)
|
47
|
-
raise 'Device not found' if dev.nil?
|
48
|
-
new(dev)
|
49
|
-
end
|
50
|
-
|
51
|
-
# returns the last device for this class
|
52
|
-
def last(*a)
|
53
|
-
dev = @deference[self].last(*a)
|
54
|
-
raise 'Device not found' if dev.nil?
|
55
|
-
new(dev)
|
56
|
-
end
|
57
|
-
|
58
|
-
# returns all devices in an array
|
59
|
-
def all
|
60
|
-
all_by_type.values.flatten
|
61
|
-
end
|
62
|
-
|
63
|
-
# returns all devices as a hash as such
|
64
|
-
# { :input => [input devices], :output => [output devices] }
|
65
|
-
def all_by_type
|
66
|
-
{
|
67
|
-
:input => @deference[self].all_by_type[:input].map { |d| @input_class.new(d) },
|
68
|
-
:output => @deference[self].all_by_type[:output].map { |d| @output_class.new(d) }
|
69
|
-
}
|
70
|
-
end
|
71
|
-
|
72
|
-
def defer_to(klass)
|
73
|
-
@deference ||= {}
|
74
|
-
@deference[self] = klass
|
75
|
-
end
|
76
|
-
|
77
|
-
def input_class(klass)
|
78
|
-
@input_class = klass
|
79
|
-
end
|
80
|
-
|
81
|
-
def output_class(klass)
|
82
|
-
@output_class = klass
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
class CongruousApiInput
|
92
|
-
|
93
|
-
include CongruousApiAdapter::Device
|
94
|
-
extend CongruousApiAdapter::Device::ClassMethods
|
95
|
-
extend Forwardable
|
96
|
-
|
97
|
-
def_delegators :@device, :buffer
|
98
|
-
|
99
|
-
#
|
100
|
-
# returns an array of MIDI event hashes as such:
|
101
|
-
# [
|
102
|
-
# { :data => [144, 60, 100], :timestamp => 1024 },
|
103
|
-
# { :data => [128, 60, 100], :timestamp => 1100 },
|
104
|
-
# { :data => [144, 40, 120], :timestamp => 1200 }
|
105
|
-
# ]
|
106
|
-
#
|
107
|
-
# the data is an array of Numeric bytes
|
108
|
-
# the timestamp is the number of millis since this input was enabled
|
109
|
-
#
|
110
|
-
def gets(*a)
|
111
|
-
@device.gets(*a)
|
112
|
-
end
|
113
|
-
|
114
|
-
#
|
115
|
-
# same as gets but returns message data as string of hex digits as such:
|
116
|
-
# [
|
117
|
-
# { :data => "904060", :timestamp => 904 },
|
118
|
-
# { :data => "804060", :timestamp => 1150 },
|
119
|
-
# { :data => "90447F", :timestamp => 1300 }
|
120
|
-
# ]
|
121
|
-
#
|
122
|
-
def gets_s(*a)
|
123
|
-
@device.gets_s(*a)
|
124
|
-
end
|
125
|
-
alias_method :gets_bytestr, :gets_s
|
126
|
-
alias_method :gets_hex, :gets_s
|
127
|
-
|
128
|
-
#
|
129
|
-
# returns an array of data bytes such as
|
130
|
-
# [144, 60, 100, 128, 60, 100, 144, 40, 120]
|
131
|
-
#
|
132
|
-
def gets_data(*a)
|
133
|
-
arr = gets
|
134
|
-
arr.map { |msg| msg[:data] }.inject { |a,b| a + b }
|
135
|
-
end
|
136
|
-
|
137
|
-
#
|
138
|
-
# returns a string of data such as
|
139
|
-
# "90406080406090447F"
|
140
|
-
#
|
141
|
-
def gets_data_s(*a)
|
142
|
-
arr = gets_bytestr
|
143
|
-
arr.map { |msg| msg[:data] }.join
|
144
|
-
end
|
145
|
-
alias_method :gets_data_bytestr, :gets_data_s
|
146
|
-
alias_method :gets_data_hex, :gets_data_s
|
147
|
-
|
148
|
-
# clears the buffer
|
149
|
-
def clear_buffer
|
150
|
-
@device.buffer.clear
|
151
|
-
end
|
152
|
-
|
153
|
-
# gets any messages in the buffer in the same format as CongruousApiInput#gets
|
154
|
-
def gets_buffer(*a)
|
155
|
-
@device.buffer
|
156
|
-
end
|
157
|
-
|
158
|
-
# gets any messages in the buffer in the same format as CongruousApiInput#gets_s
|
159
|
-
def gets_buffer_s(*a)
|
160
|
-
@device.buffer.map { |msg| msg[:data] = TypeConversion.numeric_byte_array_to_hex_string(msg[:data]); msg }
|
161
|
-
end
|
162
|
-
|
163
|
-
# gets any messages in the buffer in the same format as CongruousApiInput#gets_data
|
164
|
-
def gets_buffer_data(*a)
|
165
|
-
@device.buffer.map { |msg| msg[:data] }
|
166
|
-
end
|
167
|
-
|
168
|
-
# returns all inputs
|
169
|
-
def self.all
|
170
|
-
@deference[self].all.map { |d| new(d) }
|
171
|
-
end
|
172
|
-
|
173
|
-
end
|
174
|
-
|
175
|
-
class CongruousApiOutput
|
176
|
-
|
177
|
-
include CongruousApiAdapter::Device
|
178
|
-
extend CongruousApiAdapter::Device::ClassMethods
|
179
|
-
|
180
|
-
# sends a message to the output. the message can be:
|
181
|
-
#
|
182
|
-
# bytes eg output.puts(0x90, 0x40, 0x40)
|
183
|
-
# an array of bytes eg output.puts([0x90, 0x40, 0x40])
|
184
|
-
# or a string eg output.puts("904040")
|
185
|
-
#
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
|
4
|
+
module UniMIDI
|
5
|
+
|
6
|
+
module CongruousApiAdapter
|
7
|
+
|
8
|
+
module Device
|
9
|
+
|
10
|
+
def initialize(device_obj)
|
11
|
+
@device = device_obj
|
12
|
+
@id = @device.id
|
13
|
+
@name = @device.name
|
14
|
+
@type = @device.type
|
15
|
+
end
|
16
|
+
|
17
|
+
# enable the device for use, can be passed a block to which the device will be passed back
|
18
|
+
def open(*a, &block)
|
19
|
+
@device.open(*a)
|
20
|
+
unless block.nil?
|
21
|
+
begin
|
22
|
+
yield(self)
|
23
|
+
ensure
|
24
|
+
close
|
25
|
+
end
|
26
|
+
else
|
27
|
+
self
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# close the device
|
32
|
+
def close(*a)
|
33
|
+
@device.close(*a)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.included(base)
|
37
|
+
base.send(:attr_reader, :name)
|
38
|
+
base.send(:attr_reader, :id)
|
39
|
+
base.send(:attr_reader, :type)
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
|
44
|
+
# returns the first device for this class
|
45
|
+
def first(*a)
|
46
|
+
dev = @deference[self].first(*a)
|
47
|
+
raise 'Device not found' if dev.nil?
|
48
|
+
new(dev)
|
49
|
+
end
|
50
|
+
|
51
|
+
# returns the last device for this class
|
52
|
+
def last(*a)
|
53
|
+
dev = @deference[self].last(*a)
|
54
|
+
raise 'Device not found' if dev.nil?
|
55
|
+
new(dev)
|
56
|
+
end
|
57
|
+
|
58
|
+
# returns all devices in an array
|
59
|
+
def all
|
60
|
+
all_by_type.values.flatten
|
61
|
+
end
|
62
|
+
|
63
|
+
# returns all devices as a hash as such
|
64
|
+
# { :input => [input devices], :output => [output devices] }
|
65
|
+
def all_by_type
|
66
|
+
{
|
67
|
+
:input => @deference[self].all_by_type[:input].map { |d| @input_class.new(d) },
|
68
|
+
:output => @deference[self].all_by_type[:output].map { |d| @output_class.new(d) }
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def defer_to(klass)
|
73
|
+
@deference ||= {}
|
74
|
+
@deference[self] = klass
|
75
|
+
end
|
76
|
+
|
77
|
+
def input_class(klass)
|
78
|
+
@input_class = klass
|
79
|
+
end
|
80
|
+
|
81
|
+
def output_class(klass)
|
82
|
+
@output_class = klass
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
class CongruousApiInput
|
92
|
+
|
93
|
+
include CongruousApiAdapter::Device
|
94
|
+
extend CongruousApiAdapter::Device::ClassMethods
|
95
|
+
extend Forwardable
|
96
|
+
|
97
|
+
def_delegators :@device, :buffer
|
98
|
+
|
99
|
+
#
|
100
|
+
# returns an array of MIDI event hashes as such:
|
101
|
+
# [
|
102
|
+
# { :data => [144, 60, 100], :timestamp => 1024 },
|
103
|
+
# { :data => [128, 60, 100], :timestamp => 1100 },
|
104
|
+
# { :data => [144, 40, 120], :timestamp => 1200 }
|
105
|
+
# ]
|
106
|
+
#
|
107
|
+
# the data is an array of Numeric bytes
|
108
|
+
# the timestamp is the number of millis since this input was enabled
|
109
|
+
#
|
110
|
+
def gets(*a)
|
111
|
+
@device.gets(*a)
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# same as gets but returns message data as string of hex digits as such:
|
116
|
+
# [
|
117
|
+
# { :data => "904060", :timestamp => 904 },
|
118
|
+
# { :data => "804060", :timestamp => 1150 },
|
119
|
+
# { :data => "90447F", :timestamp => 1300 }
|
120
|
+
# ]
|
121
|
+
#
|
122
|
+
def gets_s(*a)
|
123
|
+
@device.gets_s(*a)
|
124
|
+
end
|
125
|
+
alias_method :gets_bytestr, :gets_s
|
126
|
+
alias_method :gets_hex, :gets_s
|
127
|
+
|
128
|
+
#
|
129
|
+
# returns an array of data bytes such as
|
130
|
+
# [144, 60, 100, 128, 60, 100, 144, 40, 120]
|
131
|
+
#
|
132
|
+
def gets_data(*a)
|
133
|
+
arr = gets
|
134
|
+
arr.map { |msg| msg[:data] }.inject { |a,b| a + b }
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# returns a string of data such as
|
139
|
+
# "90406080406090447F"
|
140
|
+
#
|
141
|
+
def gets_data_s(*a)
|
142
|
+
arr = gets_bytestr
|
143
|
+
arr.map { |msg| msg[:data] }.join
|
144
|
+
end
|
145
|
+
alias_method :gets_data_bytestr, :gets_data_s
|
146
|
+
alias_method :gets_data_hex, :gets_data_s
|
147
|
+
|
148
|
+
# clears the buffer
|
149
|
+
def clear_buffer
|
150
|
+
@device.buffer.clear
|
151
|
+
end
|
152
|
+
|
153
|
+
# gets any messages in the buffer in the same format as CongruousApiInput#gets
|
154
|
+
def gets_buffer(*a)
|
155
|
+
@device.buffer
|
156
|
+
end
|
157
|
+
|
158
|
+
# gets any messages in the buffer in the same format as CongruousApiInput#gets_s
|
159
|
+
def gets_buffer_s(*a)
|
160
|
+
@device.buffer.map { |msg| msg[:data] = TypeConversion.numeric_byte_array_to_hex_string(msg[:data]); msg }
|
161
|
+
end
|
162
|
+
|
163
|
+
# gets any messages in the buffer in the same format as CongruousApiInput#gets_data
|
164
|
+
def gets_buffer_data(*a)
|
165
|
+
@device.buffer.map { |msg| msg[:data] }
|
166
|
+
end
|
167
|
+
|
168
|
+
# returns all inputs
|
169
|
+
def self.all
|
170
|
+
@deference[self].all.map { |d| new(d) }
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
class CongruousApiOutput
|
176
|
+
|
177
|
+
include CongruousApiAdapter::Device
|
178
|
+
extend CongruousApiAdapter::Device::ClassMethods
|
179
|
+
|
180
|
+
# sends a message to the output. the message can be:
|
181
|
+
#
|
182
|
+
# bytes eg output.puts(0x90, 0x40, 0x40)
|
183
|
+
# an array of bytes eg output.puts([0x90, 0x40, 0x40])
|
184
|
+
# or a string eg output.puts("904040")
|
185
|
+
# if none of those types are found, unimidi will attempt
|
186
|
+
# to call to_bytes and then to_a on the object
|
187
|
+
#
|
188
|
+
def puts(*a)
|
189
|
+
case a.first
|
190
|
+
when Array then puts_bytes(*a.first)
|
191
|
+
when Numeric then puts_bytes(*a)
|
192
|
+
when String then puts_s(*a)
|
193
|
+
else
|
194
|
+
if a.first.respond_to?(:to_bytes)
|
195
|
+
puts_bytes(*a.first.to_bytes.flatten)
|
196
|
+
elsif a.first.respond_to?(:to_a)
|
197
|
+
puts_bytes(*a.first.to_a.flatten)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# sends a message to the output in a form of a string eg "904040". this method does not do
|
203
|
+
# type checking and therefore is more performant than puts
|
204
|
+
def puts_s(*a)
|
205
|
+
@device.puts_s(*a)
|
206
|
+
end
|
207
|
+
alias_method :puts_bytestr, :puts_s
|
208
|
+
alias_method :puts_hex, :puts_s
|
209
|
+
|
210
|
+
# sends a message to the output in a form of bytes eg output.puts_bytes(0x90, 0x40, 0x40).
|
211
|
+
# this method does not do type checking and therefore is more performant than puts
|
212
|
+
def puts_bytes(*a)
|
213
|
+
@device.puts_bytes(*a)
|
214
|
+
end
|
215
|
+
|
216
|
+
# returns all outputs
|
217
|
+
def self.all
|
218
|
+
@deference[self].all.map { |d| new(d) }
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
class CongruousApiDevice
|
224
|
+
extend CongruousApiAdapter::Device::ClassMethods
|
225
|
+
end
|
226
|
+
|
215
227
|
end
|
data/lib/unimidi/platform.rb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
|
4
|
-
require 'singleton'
|
5
|
-
|
6
|
-
module UniMIDI
|
7
|
-
|
8
|
-
class Platform
|
9
|
-
|
10
|
-
include Singleton
|
11
|
-
|
12
|
-
attr_reader :interface
|
13
|
-
|
14
|
-
def initialize
|
15
|
-
lib = case RUBY_PLATFORM
|
16
|
-
when /darwin/ then "ffi-coremidi"
|
17
|
-
when /java/ then "midi-jruby"
|
18
|
-
when /linux/ then "alsa-rawmidi"
|
19
|
-
when /mingw/ then "midi-winmm"
|
20
|
-
#when /win/ then "midi-winmm"
|
21
|
-
end
|
22
|
-
require("unimidi/adapter/#{lib}")
|
23
|
-
@interface = case RUBY_PLATFORM
|
24
|
-
when /darwin/ then CoreMIDIAdapter
|
25
|
-
when /java/ then MIDIJRubyAdapter
|
26
|
-
when /linux/ then AlsaRawMIDIAdapter
|
27
|
-
when /mingw/ then MIDIWinMMAdapter
|
28
|
-
#when /win/ then MIDIWinMMAdapter
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
module UniMIDI
|
7
|
+
|
8
|
+
class Platform
|
9
|
+
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_reader :interface
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
lib = case RUBY_PLATFORM
|
16
|
+
when /darwin/ then "ffi-coremidi"
|
17
|
+
when /java/ then "midi-jruby"
|
18
|
+
when /linux/ then "alsa-rawmidi"
|
19
|
+
when /mingw/ then "midi-winmm"
|
20
|
+
#when /win/ then "midi-winmm"
|
21
|
+
end
|
22
|
+
require("unimidi/adapter/#{lib}")
|
23
|
+
@interface = case RUBY_PLATFORM
|
24
|
+
when /darwin/ then CoreMIDIAdapter
|
25
|
+
when /java/ then MIDIJRubyAdapter
|
26
|
+
when /linux/ then AlsaRawMIDIAdapter
|
27
|
+
when /mingw/ then MIDIWinMMAdapter
|
28
|
+
#when /win/ then MIDIWinMMAdapter
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|