unimidi 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
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,63 @@
1
+ = UniMIDI
2
+
3
+ == Summary
4
+
5
+ Platform independent realtime MIDI input and output for Ruby.
6
+
7
+ == Features
8
+
9
+ * Supports Linux, JRuby, OSX, Windows and Cygwin
10
+ * Both input and output to and from multiple devices concurrently
11
+ * Agnostically handle different MIDI and SysEx Message types
12
+
13
+ == Requirements
14
+
15
+ Ruby 1.9.2 or JRuby 1.6.1 are strongly recommended
16
+
17
+ One of the following libraries is required based on what platform is being used. It should install automatically when you install the unimidi gem
18
+
19
+ Platform
20
+
21
+ * JRuby: {midi-jruby}[http://github.com/arirusso/midi-jruby]
22
+ * Linux: {alsa-rawmidi}[http://github.com/arirusso/alsa-rawmidi]
23
+ * OSX: {ffi-coremidi}[http://github.com/arirusso/ffi-coremidi]
24
+ * Windows/Cygwin: {midi-winmm}[http://github.com/arirusso/midi-winmm]
25
+
26
+ == Install
27
+
28
+ gem install unimidi
29
+
30
+ No compilation required
31
+
32
+ == Examples
33
+
34
+ * {input}[http://github.com/arirusso/unimidi/blob/master/examples/input.rb]
35
+ * {output}[http://github.com/arirusso/unimidi/blob/master/examples/output.rb]
36
+
37
+ {more}[http://github.com/arirusso/unimidi/blob/master/examples]
38
+
39
+ == Tests
40
+
41
+ * please see {test/config.rb}[http://github.com/arirusso/unimidi/blob/master/test/config.rb] before running tests
42
+
43
+ == Documentation
44
+
45
+ * {rdoc}[http://rdoc.info/gems/unimidi]
46
+
47
+ == If you are using JRuby
48
+
49
+ A couple of notes
50
+
51
+ * You must be in 1.9 mode. This is normally accomplished by passing --1.9 to JRuby at the command line. For testing in 1.9 mode, use
52
+ jruby --1.9 -S rake test
53
+ * javax.sound has some documented issues with SysEx messages in some versions OSX Snow Leopard which do affect this library.
54
+
55
+ == Author
56
+
57
+ {Ari Russo}[http://github.com/arirusso] <ari.russo at gmail.com>
58
+
59
+ == License
60
+
61
+ Apache 2.0, See the file LICENSE
62
+
63
+ Copyright (c) 2010-2011 Ari Russo
data/bin/unimidi ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+
4
+ require 'unimidi'
5
+
6
+ opts = ARGV.length > 1 ? ARGV.slice(1, ARGV.length-1) : {}
7
+
8
+ raise "No command specified" if ARGV.first.nil?
9
+
10
+ UniMIDI.command(ARGV.first.to_sym, opts)
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'alsa-rawmidi'
5
+
6
+ module UniMIDI
7
+
8
+ module AlsaRawMIDIAdapter
9
+
10
+ class Input < CongruousApiInput
11
+ defer_to AlsaRawMIDI::Input
12
+ end
13
+
14
+ class Output < CongruousApiOutput
15
+ defer_to AlsaRawMIDI::Output
16
+ end
17
+
18
+ class Device < CongruousApiDevice
19
+ defer_to AlsaRawMIDI::Device
20
+ input_class Input
21
+ output_class Output
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'coremidi'
5
+
6
+ module UniMIDI
7
+
8
+ module CoreMIDIAdapter
9
+
10
+ class Input < CongruousApiInput
11
+ defer_to CoreMIDI::Input
12
+ end
13
+
14
+ class Output < CongruousApiOutput
15
+ defer_to CoreMIDI::Output
16
+ end
17
+
18
+ class Device < CongruousApiDevice
19
+ defer_to CoreMIDI::Entity
20
+ input_class Input
21
+ output_class Output
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'midi-jruby'
5
+
6
+ module UniMIDI
7
+
8
+ module MIDIJRubyAdapter
9
+
10
+ class Input < CongruousApiInput
11
+ defer_to MIDIJRuby::Input
12
+ end
13
+
14
+ class Output < CongruousApiOutput
15
+ defer_to MIDIJRuby::Output
16
+ end
17
+
18
+ class Device < CongruousApiDevice
19
+ defer_to MIDIJRuby::Device
20
+ input_class Input
21
+ output_class Output
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'midi-winmm'
5
+
6
+ module UniMIDI
7
+
8
+ module MIDIWinMMAdapter
9
+
10
+ class Input < CongruousApiInput
11
+ defer_to MIDIWinMM::Input
12
+ end
13
+
14
+ class Output < CongruousApiOutput
15
+ defer_to MIDIWinMM::Output
16
+ end
17
+
18
+ class Device < CongruousApiDevice
19
+ defer_to MIDIWinMM::Device
20
+ input_class Input
21
+ output_class Output
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,215 @@
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
+ def puts(*a)
187
+ @device.puts(*a)
188
+ end
189
+
190
+ # sends a message to the output in a form of a string eg "904040". this method does not do
191
+ # type checking and therefore is more performant than puts
192
+ def puts_s(*a)
193
+ @device.puts_s(*a)
194
+ end
195
+ alias_method :puts_bytestr, :puts_s
196
+ alias_method :puts_hex, :puts_s
197
+
198
+ # sends a message to the output in a form of bytes eg output.puts_bytes(0x90, 0x40, 0x40).
199
+ # this method does not do type checking and therefore is more performant than puts
200
+ def puts_bytes(*a)
201
+ @device.puts_bytes(*a)
202
+ end
203
+
204
+ # returns all outputs
205
+ def self.all
206
+ @deference[self].all.map { |d| new(d) }
207
+ end
208
+
209
+ end
210
+
211
+ class CongruousApiDevice
212
+ extend CongruousApiAdapter::Device::ClassMethods
213
+ end
214
+
215
+ end
@@ -0,0 +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
+
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ module UniMIDI
5
+
6
+ module TypeConversion
7
+
8
+ # byte array to string of hex bytes
9
+ def numeric_byte_array_to_hex_string(bytes)
10
+ bytes.map { |b| b.hex }.join
11
+ end
12
+
13
+ end
14
+
15
+ end
data/lib/unimidi.rb ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # A realtime MIDI interface for Ruby
4
+ # (c)2010-2011 Ari Russo and licensed under the Apache 2.0 License
5
+ #
6
+
7
+ module UniMIDI
8
+
9
+ VERSION = "0.1.14"
10
+
11
+ end
12
+
13
+ require 'forwardable'
14
+
15
+ require 'unimidi/congruous_api_adapter'
16
+ require 'unimidi/platform'
17
+ require 'unimidi/type_conversion'
18
+
19
+ module UniMIDI
20
+ extend(Platform.instance.interface)
21
+ include(Platform.instance.interface)
22
+
23
+ def self.command(command, options = {})
24
+ if [:l, :list, :list_devices].include?(command)
25
+ require 'pp'
26
+ pp Device::all
27
+ else
28
+ raise "Command #{command.to_s} not found"
29
+ end
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unimidi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.14
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ari Russo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-05-23 00:00:00.000000000 -04:00
13
+ default_executable: unimidi
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: alsa-rawmidi
17
+ requirement: &9446868 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *9446868
26
+ - !ruby/object:Gem::Dependency
27
+ name: ffi-coremidi
28
+ requirement: &9446532 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *9446532
37
+ - !ruby/object:Gem::Dependency
38
+ name: midi-jruby
39
+ requirement: &9446244 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *9446244
48
+ - !ruby/object:Gem::Dependency
49
+ name: midi-winmm
50
+ requirement: &9445956 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *9445956
59
+ description: Platform Independent, realtime MIDI input and output for Ruby.
60
+ email:
61
+ - ari.russo@gmail.com
62
+ executables:
63
+ - unimidi
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - bin/unimidi
68
+ - lib/unimidi/adapter/alsa-rawmidi.rb
69
+ - lib/unimidi/adapter/ffi-coremidi.rb
70
+ - lib/unimidi/adapter/midi-jruby.rb
71
+ - lib/unimidi/adapter/midi-winmm.rb
72
+ - lib/unimidi/congruous_api_adapter.rb
73
+ - lib/unimidi/platform.rb
74
+ - lib/unimidi/type_conversion.rb
75
+ - lib/unimidi.rb
76
+ - LICENSE
77
+ - README.rdoc
78
+ has_rdoc: true
79
+ homepage: http://github.com/arirusso/unimidi
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: 1.3.6
97
+ requirements: []
98
+ rubyforge_project: unimidi
99
+ rubygems_version: 1.5.2
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Realtime MIDI input and output for Ruby.
103
+ test_files: []