unimidi 0.3.5 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed90b779061c05a4d9de9aaf94175fc0f616df1a
4
- data.tar.gz: 0dc1da5d5695baed5abbc980c7e322309409b54b
3
+ metadata.gz: a75ecec80f113f9831ddabe50fbb3a00e183faae
4
+ data.tar.gz: 174c3ec107b0d696f8780708c83a9abf8a1e33ca
5
5
  SHA512:
6
- metadata.gz: bf13056a209f9b9dd456f2d2fcfa8a7859f290ec2957d334e91a163911f74c892d292d1c12ea947cd8f86c26a089e6862c6fd38ee5db54b80f43d75b346cff1e
7
- data.tar.gz: 2d6cf96e42bbe5384bf41212c2db0abc1aea88bdeca82b66ba744069aaf0f54470e7e27de3ec23c040d403131108e6712ccb251cf8bfc98ab59d411564f7d10e
6
+ metadata.gz: f1b430c23cb93b0373834bab0c66a25286dc5ca6bcee99e963b3d40892781f7b076b00a13ada2828bc871d035706d63d2fa774e101a4c965df1b28ea05bcc5e3
7
+ data.tar.gz: cae4027fefcbb3b0a06cebbe1eefba944b7ca55419fc025cf752f1604915ce19845a70290aeae3cd941491c30b8dc5b53b4ffb7681235221356be95d0d7fa195
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2010-2013 Ari Russo
1
+ Copyright 2010-2014 Ari Russo
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -9,14 +9,14 @@ Also see [MicroMIDI](http://github.com/arirusso/micromidi) which builds a full M
9
9
  * Supports Linux, JRuby, OSX, Windows and Cygwin
10
10
  * No compilation required
11
11
  * Both input and output to and from multiple devices concurrently
12
- * Agnostically handle different MIDI and SysEx Message types
12
+ * Generalized handling of different MIDI and SysEx Message types
13
13
  * (OSX Only) Use IAC to internally route MIDI to other programs
14
14
 
15
15
  ### Requirements
16
16
 
17
17
  Using Ruby 1.9.2 or JRuby 1.6.1 (or newer) is strongly recommended. JRuby should be run in 1.9 mode where applicable
18
18
 
19
- UniMIDI uses one of the following libraries, depending on which platform you're using it on. The necessary library should install automatically with the unimidi gem. In some uncommon cases, they will all install
19
+ UniMIDI uses one of the following libraries, depending on which platform you're using it on. The necessary library should install automatically with the unimidi gem.
20
20
 
21
21
  Platform
22
22
 
@@ -84,4 +84,4 @@ See below for additional notes on testing with JRuby
84
84
 
85
85
  Apache 2.0, See the file LICENSE
86
86
 
87
- Copyright (c) 2010-2013 Ari Russo
87
+ Copyright (c) 2010-2014 Ari Russo
@@ -1,34 +1,24 @@
1
- # A realtime MIDI interface for Ruby
2
- # (c)2010-2013 Ari Russo and licensed under the Apache 2.0 License
3
- module UniMIDI
4
-
5
- VERSION = "0.3.5"
6
-
7
- end
8
-
9
- # libs
10
- require "forwardable"
11
- require "singleton"
1
+ #
2
+ # Realtime MIDI IO for Ruby
3
+ #
4
+ # (c)2010-2014 Ari Russo and licensed under the Apache 2.0 License
5
+ #
12
6
 
13
7
  # modules
14
- require "unimidi/congruous_api_adapter"
8
+ require "unimidi/command"
9
+ require "unimidi/device"
10
+ require "unimidi/loader"
11
+ require "unimidi/platform"
15
12
  require "unimidi/type_conversion"
16
13
 
17
14
  # classes
18
- require "unimidi/platform"
15
+ require "unimidi/input"
16
+ require "unimidi/output"
19
17
 
20
18
  module UniMIDI
21
- extend(Platform.instance.interface)
22
- include(Platform.instance.interface)
23
-
24
- def self.command(command, options = {})
25
- if [:l, :list, :list_devices].include?(command)
26
- puts "input:"
27
- Input.list
28
- puts "output:"
29
- Output.list
30
- else
31
- raise "Command #{command.to_s} not found"
32
- end
33
- end
19
+
20
+ VERSION = "0.4.4"
21
+
22
+ Platform.bootstrap
23
+
34
24
  end
@@ -1,25 +1,30 @@
1
- require 'alsa-rawmidi'
1
+ require "alsa-rawmidi"
2
2
 
3
3
  module UniMIDI
4
4
 
5
- module AlsaRawMIDIAdapter
6
-
7
- class Input < CongruousApiInput
8
- defer_to AlsaRawMIDI::Input
9
- device_class AlsaRawMIDI::Device
10
- end
5
+ module Adapter
6
+
7
+ # Load underlying devices using the alsa-rawmidi gem
8
+ module AlsaRawMIDI
9
+
10
+ module Loader
11
+
12
+ extend self
13
+
14
+ # @return [Array<AlsaRawMIDI::Input>]
15
+ def inputs
16
+ ::AlsaRawMIDI::Device.all_by_type[:input]
17
+ end
18
+
19
+ # @return [Array<AlsaRawMIDI::Output>]
20
+ def outputs
21
+ ::AlsaRawMIDI::Device.all_by_type[:output]
22
+ end
23
+
24
+ end
11
25
 
12
- class Output < CongruousApiOutput
13
- defer_to AlsaRawMIDI::Output
14
- device_class AlsaRawMIDI::Device
15
- end
16
-
17
- class Device < CongruousApiDevice
18
- defer_to AlsaRawMIDI::Device
19
- input_class Input
20
- output_class Output
21
26
  end
22
-
27
+
23
28
  end
24
29
 
25
30
  end
@@ -1,34 +1,30 @@
1
- require 'coremidi'
1
+ require "coremidi"
2
2
 
3
3
  module UniMIDI
4
4
 
5
- module CoreMIDIAdapter
6
-
7
- class Input < CongruousApiInput
8
- defer_to CoreMIDI::Source
9
- device_class CoreMIDI::Endpoint
10
- end
5
+ module Adapter
6
+
7
+ # Load underlying devices using the coremidi gem
8
+ module CoreMIDI
9
+
10
+ module Loader
11
+
12
+ extend self
13
+
14
+ # @return [Array<CoreMIDI::Source>]
15
+ def inputs
16
+ ::CoreMIDI::Endpoint.all_by_type[:source]
17
+ end
18
+
19
+ # @return [Array<CoreMIDI::Destination>]
20
+ def outputs
21
+ ::CoreMIDI::Endpoint.all_by_type[:destination]
22
+ end
11
23
 
12
- class Output < CongruousApiOutput
13
- defer_to CoreMIDI::Destination
14
- device_class CoreMIDI::Endpoint
15
- end
16
-
17
- class Device < CongruousApiDevice
18
- defer_to CoreMIDI::Endpoint
19
- input_class Input
20
- output_class Output
21
-
22
- def self.populate
23
- klass = @deference[self].respond_to?(:all_by_type) ? @deference[self] : @device_class
24
- @devices = {
25
- :input => klass.all_by_type[:source].map { |d| @input_class.new(d) },
26
- :output => klass.all_by_type[:destination].map { |d| @output_class.new(d) }
27
- }
28
24
  end
29
-
25
+
30
26
  end
31
-
27
+
32
28
  end
33
29
 
34
30
  end
@@ -1,23 +1,28 @@
1
- require 'midi-jruby'
1
+ require "midi-jruby"
2
2
 
3
3
  module UniMIDI
4
4
 
5
- module MIDIJRubyAdapter
6
-
7
- class Input < CongruousApiInput
8
- defer_to MIDIJRuby::Input
9
- device_class MIDIJRuby::Device
10
- end
5
+ module Adapter
6
+
7
+ # Load underlying devices using the midi-jruby gem
8
+ module MIDIJRuby
9
+
10
+ module Loader
11
+
12
+ extend self
13
+
14
+ # @return [Array<MIDIJRuby::Input>]
15
+ def inputs
16
+ ::MIDIJRuby::Device.all_by_type[:input]
17
+ end
18
+
19
+ # @return [Array<MIDIJRuby::Output>]
20
+ def outputs
21
+ ::MIDIJRuby::Device.all_by_type[:output]
22
+ end
23
+
24
+ end
11
25
 
12
- class Output < CongruousApiOutput
13
- defer_to MIDIJRuby::Output
14
- device_class MIDIJRuby::Device
15
- end
16
-
17
- class Device < CongruousApiDevice
18
- defer_to MIDIJRuby::Device
19
- input_class Input
20
- output_class Output
21
26
  end
22
27
 
23
28
  end
@@ -1,23 +1,28 @@
1
- require 'midi-winmm'
1
+ require "midi-winmm"
2
2
 
3
3
  module UniMIDI
4
4
 
5
- module MIDIWinMMAdapter
6
-
7
- class Input < CongruousApiInput
8
- defer_to MIDIWinMM::Input
9
- device_class MIDIWinMM::Device
10
- end
5
+ module Adapter
6
+
7
+ # Load underlying devices using the midi-winmm gem
8
+ module MIDIWinMM
9
+
10
+ module Loader
11
+
12
+ extend self
13
+
14
+ # @return [Array<MIDIWinMM::Input>]
15
+ def inputs
16
+ ::MIDIWinMM::Device.all_by_type[:input]
17
+ end
18
+
19
+ # @return [Array<MIDIWinMM::Output>]
20
+ def outputs
21
+ ::MIDIWinMM::Device.all_by_type[:output]
22
+ end
23
+
24
+ end
11
25
 
12
- class Output < CongruousApiOutput
13
- defer_to MIDIWinMM::Output
14
- device_class MIDIWinMM::Device
15
- end
16
-
17
- class Device < CongruousApiDevice
18
- defer_to MIDIWinMM::Device
19
- input_class Input
20
- output_class Output
21
26
  end
22
27
 
23
28
  end
@@ -0,0 +1,26 @@
1
+ module UniMIDI
2
+
3
+ # Module for command-line use of UniMIDI. Used by the bin/unimidi script
4
+ module Command
5
+
6
+ extend self
7
+
8
+ # Execute a command
9
+ # @param [Symbol] command
10
+ # @param [Hash] options
11
+ # @return [Boolean]
12
+ def exec(command, options = {})
13
+ if [:l, :list, :list_devices].include?(command)
14
+ puts "input:"
15
+ Input.list
16
+ puts "output:"
17
+ Output.list
18
+ true
19
+ else
20
+ raise "Command #{command.to_s} not found"
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,182 @@
1
+ module UniMIDI
2
+
3
+ # Common logic that is shared by both Input and Output devices
4
+ module Device
5
+
6
+ # Methods that are shared by both Input and Output classes
7
+ module ClassMethods
8
+
9
+ include Enumerable
10
+
11
+ # Iterate over all devices of this direction (eg Input, Output)
12
+ def each(&block)
13
+ all.each { |device| yield(device) }
14
+ end
15
+
16
+ # Prints ids and names of each device to the console
17
+ # @return [Array<String>]
18
+ def list
19
+ all.map do |device|
20
+ name = device.pretty_name
21
+ puts(name)
22
+ name
23
+ end
24
+ end
25
+
26
+ # Shortcut to select a device by its name
27
+ # @param [String, Symbol] name
28
+ # @return [Input, Output]
29
+ def find_by_name(name)
30
+ all.find { |device| name.to_s == device.name }
31
+ end
32
+
33
+ # Streamlined console prompt that asks the user to select a device
34
+ # When their input is received, the device is selected and enabled
35
+ def gets(&block)
36
+ device = nil
37
+ class_name = self.name.split("::").last.downcase
38
+ puts ""
39
+ puts "Select a MIDI #{class_name}..."
40
+ while device.nil?
41
+ list
42
+ print "> "
43
+ selection = $stdin.gets.chomp
44
+ if selection != ""
45
+ selection = Integer(selection) rescue nil
46
+ device = all.find { |d| d.id == selection }
47
+ end
48
+ end
49
+ device.open(&block) unless device.enabled?
50
+ device
51
+ end
52
+
53
+ # Select the first device and enable it
54
+ # @return [Input, Output]
55
+ def first(&block)
56
+ use_device(all.first, &block)
57
+ end
58
+
59
+ # Select the last device and enable it
60
+ # @return [Input, Output]
61
+ def last(&block)
62
+ use_device(all.last, &block)
63
+ end
64
+
65
+ # Select the device at the given index and enable it
66
+ # @param [Fixnum] index
67
+ # @return [Input, Output]
68
+ def use(index, &block)
69
+ index = case index
70
+ when :first then 0
71
+ when :last then all.size - 1
72
+ else index
73
+ end
74
+ use_device(all[index], &block)
75
+ end
76
+ alias_method :open, :use
77
+
78
+ # Select the device at the given index
79
+ # @param [Fixnum] index
80
+ # @return [Input, Output]
81
+ def [](index)
82
+ all[index]
83
+ end
84
+
85
+ private
86
+
87
+ # Enable the given device
88
+ # @param [Input, Output] device
89
+ # @return [Input, Output]
90
+ def use_device(device, &block)
91
+ device.open(&block) unless device.enabled?
92
+ device
93
+ end
94
+
95
+ end
96
+
97
+ # Methods that are shared by both Input and Output instances
98
+ module InstanceMethods
99
+
100
+ # @param [AlsaRawMIDI::Input, AlsaRawMIDI::Output, CoreMIDI::Destination, CoreMIDI::Source, MIDIJRuby::Input, MIDIJRuby::Output, MIDIWinMM::Input, MIDIWinMM::Output] device
101
+ def initialize(device)
102
+ @device = device
103
+ @enabled = false
104
+
105
+ populate_from_device
106
+ end
107
+
108
+ # Is this device ready for io?
109
+ # @return [Boolean]
110
+ def enabled?
111
+ @enabled = true if @device.enabled # keep the adapter in sync
112
+ @enabled
113
+ end
114
+
115
+ # Enable the device for use
116
+ # Params are passed to the underlying device object
117
+ # Can be passed a block to which the device will be passed in as the yieldparam
118
+ # @param [*Object] args
119
+ # @return [Input, Output] self
120
+ def open(*args, &block)
121
+ @device.open(*args) unless enabled?
122
+ @enabled = true
123
+ if block_given?
124
+ begin
125
+ yield(self)
126
+ ensure
127
+ close
128
+ end
129
+ else
130
+ at_exit do
131
+ close
132
+ end
133
+ self
134
+ end
135
+ end
136
+
137
+ # A human readable display name for this device
138
+ # @return [String]
139
+ def pretty_name
140
+ "#{id}) #{name}"
141
+ end
142
+
143
+ # Close the device
144
+ # Params are passed to the underlying device object
145
+ # @param [*Object] args
146
+ # @return [Boolean]
147
+ def close(*args)
148
+ @device.close(*args)
149
+ true
150
+ end
151
+
152
+ # Add attributes for the device instance
153
+ # :direction, :id, :name
154
+ def self.included(base)
155
+ base.send(:attr_reader, :direction)
156
+ base.send(:attr_reader, :id)
157
+ base.send(:attr_reader, :name)
158
+ base.send(:alias_method, :type, :direction)
159
+ end
160
+
161
+ private
162
+
163
+ # Populate the direction attribute
164
+ def populate_direction
165
+ @direction = case @device.type
166
+ when :source, :input then :input
167
+ when :destination, :output then :output
168
+ end
169
+ end
170
+
171
+ # Populate attributes from the underlying device object
172
+ def populate_from_device
173
+ @id = @device.id
174
+ @name = @device.name
175
+ populate_direction
176
+ end
177
+
178
+ end
179
+
180
+ end
181
+
182
+ end