unimidi 0.1.14

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 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: []