ffi-coremidi 0.3.5 → 0.3.6
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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/lib/coremidi.rb +2 -2
- data/lib/coremidi/destination.rb +16 -18
- data/lib/coremidi/endpoint.rb +10 -8
- data/lib/coremidi/source.rb +15 -17
- data/test/helper.rb +21 -13
- data/test/input_buffer_test.rb +4 -4
- data/test/io_test.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28b485379651851b48abf76f539672cdc9f08a97
|
4
|
+
data.tar.gz: 66eb8e0c88b90cd4ef8eaa3547964d5043266a9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42e781c9108831e86ec68f04d9873ace1d45c1d093195bc24207e9a5e4cd8f331da8bec8c37659152422e7d3ff184f081463048e6c92308ebc25af62c7a3d0a6
|
7
|
+
data.tar.gz: f1cf748819e912dabb989495fc2359d0c26593a20e4dcb1aa5cf57605f61bcc2e172f53630f87e70f571c064b911991e826e50d199af9f80c60b2d561da0aa18
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ Note that in the interest of allowing people on other platforms to utilize your
|
|
12
12
|
* Input and output on multiple devices concurrently
|
13
13
|
* Generalized handling of different MIDI Message types (including SysEx)
|
14
14
|
* Timestamped input events
|
15
|
-
* Patch MIDI via software to other programs using IAC
|
15
|
+
* Patch MIDI via software to other programs using IAC
|
16
16
|
|
17
17
|
### Requirements
|
18
18
|
|
@@ -23,11 +23,11 @@ Note that in the interest of allowing people on other platforms to utilize your
|
|
23
23
|
If you're using Bundler, add this line to your application's Gemfile:
|
24
24
|
|
25
25
|
`gem "ffi-coremidi"`
|
26
|
-
|
26
|
+
|
27
27
|
Otherwise
|
28
28
|
|
29
29
|
`gem install ffi-coremidi`
|
30
|
-
|
30
|
+
|
31
31
|
### Documentation
|
32
32
|
|
33
33
|
[rdoc](http://rubydoc.info/github/arirusso/ffi-coremidi)
|
@@ -48,4 +48,4 @@ Also thank you to [Jeremy Voorhis](http://github.com/jvoorhis) for some useful d
|
|
48
48
|
|
49
49
|
Apache 2.0, See the file LICENSE
|
50
50
|
|
51
|
-
Copyright (c) 2011-
|
51
|
+
Copyright (c) 2011-2015 [Ari Russo](http://github.com/arirusso)
|
data/lib/coremidi.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# ffi-coremidi
|
2
2
|
#
|
3
3
|
# Realtime MIDI IO with Ruby for OSX
|
4
|
-
# (c)2011-
|
4
|
+
# (c)2011-2015 Ari Russo
|
5
5
|
|
6
6
|
# libs
|
7
7
|
require "ffi"
|
@@ -19,5 +19,5 @@ require "coremidi/source"
|
|
19
19
|
require "coremidi/destination"
|
20
20
|
|
21
21
|
module CoreMIDI
|
22
|
-
VERSION = "0.3.
|
22
|
+
VERSION = "0.3.6"
|
23
23
|
end
|
data/lib/coremidi/destination.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module CoreMIDI
|
2
2
|
|
3
|
-
#
|
3
|
+
# Type of endpoint used for output
|
4
4
|
class Destination
|
5
5
|
|
6
6
|
include Endpoint
|
@@ -23,9 +23,9 @@ module CoreMIDI
|
|
23
23
|
# @return [Boolean]
|
24
24
|
def puts_s(data)
|
25
25
|
data = data.dup
|
26
|
-
|
26
|
+
bytes = []
|
27
27
|
until (str = data.slice!(0,2)).eql?("")
|
28
|
-
|
28
|
+
bytes << str.hex
|
29
29
|
end
|
30
30
|
puts_bytes(*bytes)
|
31
31
|
true
|
@@ -47,10 +47,10 @@ module CoreMIDI
|
|
47
47
|
# @param [*Array<Fixnum>, *Array<String>, *Fixnum, *String] args
|
48
48
|
# @return [Boolean]
|
49
49
|
def puts(*args)
|
50
|
-
|
50
|
+
case args.first
|
51
51
|
when Array then args.each { |arg| puts(*arg) }
|
52
|
-
|
53
|
-
|
52
|
+
when Fixnum then puts_bytes(*args)
|
53
|
+
when String then puts_bytestr(*args)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
alias_method :write, :puts
|
@@ -58,14 +58,12 @@ module CoreMIDI
|
|
58
58
|
# Enable this device
|
59
59
|
# @return [Destination]
|
60
60
|
def enable(options = {}, &block)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
close
|
68
|
-
end
|
61
|
+
@enabled = true unless @enabled
|
62
|
+
if block_given?
|
63
|
+
begin
|
64
|
+
yield(self)
|
65
|
+
ensure
|
66
|
+
close
|
69
67
|
end
|
70
68
|
end
|
71
69
|
self
|
@@ -78,7 +76,7 @@ module CoreMIDI
|
|
78
76
|
def self.first
|
79
77
|
Endpoint.first(:destination)
|
80
78
|
end
|
81
|
-
|
79
|
+
|
82
80
|
# Shortcut to the last output endpoint available
|
83
81
|
# @return [Destination]
|
84
82
|
def self.last
|
@@ -90,7 +88,7 @@ module CoreMIDI
|
|
90
88
|
def self.all
|
91
89
|
Endpoint.all_by_type[:destination]
|
92
90
|
end
|
93
|
-
|
91
|
+
|
94
92
|
protected
|
95
93
|
|
96
94
|
# Base initialization for this endpoint -- done whether or not the endpoint is enabled to
|
@@ -128,9 +126,9 @@ module CoreMIDI
|
|
128
126
|
|
129
127
|
SysexCompletionCallback =
|
130
128
|
API.get_callback([:pointer]) do |sysex_request_ptr|
|
131
|
-
|
129
|
+
# this isn't working for some reason. as of now, it's not needed though
|
132
130
|
end
|
133
|
-
|
131
|
+
|
134
132
|
# Initialize a coremidi port for this endpoint
|
135
133
|
def initialize_port
|
136
134
|
port = API.create_midi_output_port(@client, @resource_id, @name)
|
data/lib/coremidi/endpoint.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module CoreMIDI
|
2
2
|
|
3
|
-
# A
|
3
|
+
# A source or destination of a 16-channel MIDI stream
|
4
|
+
#
|
5
|
+
# https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html
|
4
6
|
module Endpoint
|
5
|
-
|
7
|
+
|
6
8
|
extend Forwardable
|
7
9
|
|
8
10
|
attr_reader :enabled, # has the endpoint been initialized?
|
@@ -10,7 +12,7 @@ module CoreMIDI
|
|
10
12
|
:id,
|
11
13
|
:resource_id, # :input or :output
|
12
14
|
:type
|
13
|
-
|
15
|
+
|
14
16
|
def_delegators :entity, :manufacturer, :model, :name
|
15
17
|
|
16
18
|
alias_method :enabled?, :enabled
|
@@ -23,13 +25,13 @@ module CoreMIDI
|
|
23
25
|
@type = get_type
|
24
26
|
@enabled = false
|
25
27
|
end
|
26
|
-
|
28
|
+
|
27
29
|
# Is this endpoint online?
|
28
30
|
# @return [Boolean]
|
29
31
|
def online?
|
30
32
|
@entity.online? && connect?
|
31
33
|
end
|
32
|
-
|
34
|
+
|
33
35
|
# Set the id for this endpoint (the id is immutable)
|
34
36
|
# @param [Fixnum] val
|
35
37
|
# @return [Fixnum]
|
@@ -83,9 +85,9 @@ module CoreMIDI
|
|
83
85
|
case type
|
84
86
|
when :source then Source
|
85
87
|
when :destination then Destination
|
86
|
-
end
|
88
|
+
end
|
87
89
|
end
|
88
|
-
|
90
|
+
|
89
91
|
protected
|
90
92
|
|
91
93
|
# Constructs the endpoint type (eg source, destination) for easy consumption
|
@@ -93,7 +95,7 @@ module CoreMIDI
|
|
93
95
|
class_name = self.class.name.split('::').last
|
94
96
|
class_name.downcase.to_sym
|
95
97
|
end
|
96
|
-
|
98
|
+
|
97
99
|
# Enables the coremidi MIDI client that will go with this endpoint
|
98
100
|
def enable_client
|
99
101
|
client = API.create_midi_client(@resource_id, @name)
|
data/lib/coremidi/source.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module CoreMIDI
|
2
2
|
|
3
|
-
#
|
3
|
+
# Type of endpoint used for input
|
4
4
|
class Source
|
5
5
|
|
6
6
|
include Endpoint
|
@@ -30,7 +30,7 @@ module CoreMIDI
|
|
30
30
|
end
|
31
31
|
alias_method :read, :gets
|
32
32
|
|
33
|
-
# Same as Source#gets except that it returns message data as string of hex
|
33
|
+
# Same as Source#gets except that it returns message data as string of hex
|
34
34
|
# digits as such:
|
35
35
|
# [
|
36
36
|
# { :data => "904060", :timestamp => 904 },
|
@@ -41,7 +41,7 @@ module CoreMIDI
|
|
41
41
|
# @return [Array<Hash>]
|
42
42
|
def gets_s
|
43
43
|
messages = gets
|
44
|
-
messages.each do |message|
|
44
|
+
messages.each do |message|
|
45
45
|
message[:data] = TypeConversion.numeric_bytes_to_hex_string(message[:data])
|
46
46
|
end
|
47
47
|
messages
|
@@ -51,14 +51,12 @@ module CoreMIDI
|
|
51
51
|
# Enable this the input for use; can be passed a block
|
52
52
|
# @return [Source]
|
53
53
|
def enable(options = {}, &block)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
close
|
61
|
-
end
|
54
|
+
@enabled = true unless @enabled
|
55
|
+
if block_given?
|
56
|
+
begin
|
57
|
+
yield(self)
|
58
|
+
ensure
|
59
|
+
close
|
62
60
|
end
|
63
61
|
end
|
64
62
|
self
|
@@ -105,9 +103,9 @@ module CoreMIDI
|
|
105
103
|
|
106
104
|
protected
|
107
105
|
|
108
|
-
# Base initialization for this endpoint -- done whether or not the endpoint is enabled to check whether
|
106
|
+
# Base initialization for this endpoint -- done whether or not the endpoint is enabled to check whether
|
109
107
|
# it is truly available for use
|
110
|
-
def connect
|
108
|
+
def connect
|
111
109
|
enable_client
|
112
110
|
initialize_port
|
113
111
|
@resource = API.MIDIEntityGetSource(@entity.resource, @resource_id)
|
@@ -134,7 +132,7 @@ module CoreMIDI
|
|
134
132
|
@sysex_buffer.clear
|
135
133
|
end
|
136
134
|
end
|
137
|
-
@buffer << get_message_formatted(bytes, timestamp) if @sysex_buffer.empty?
|
135
|
+
@buffer << get_message_formatted(bytes, timestamp) if @sysex_buffer.empty?
|
138
136
|
@buffer
|
139
137
|
end
|
140
138
|
|
@@ -214,9 +212,9 @@ module CoreMIDI
|
|
214
212
|
# Give a message its timestamp and package it in a Hash
|
215
213
|
# @return [Hash]
|
216
214
|
def get_message_formatted(raw, time)
|
217
|
-
{
|
218
|
-
:data => raw,
|
219
|
-
:timestamp => timestamp(time)
|
215
|
+
{
|
216
|
+
:data => raw,
|
217
|
+
:timestamp => timestamp(time)
|
220
218
|
}
|
221
219
|
end
|
222
220
|
|
data/test/helper.rb
CHANGED
@@ -1,41 +1,49 @@
|
|
1
1
|
dir = File.dirname(File.expand_path(__FILE__))
|
2
2
|
$LOAD_PATH.unshift dir + "/../lib"
|
3
3
|
|
4
|
-
require "
|
4
|
+
require "minitest/autorun"
|
5
5
|
require "mocha/test_unit"
|
6
6
|
require "shoulda-context"
|
7
|
+
|
7
8
|
require "coremidi"
|
8
9
|
|
9
10
|
module TestHelper
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
|
12
|
+
extend self
|
13
|
+
|
14
|
+
def device
|
15
|
+
@device ||= select_devices
|
16
|
+
end
|
17
|
+
|
18
|
+
def select_devices
|
19
|
+
@device ||= {}
|
13
20
|
{ :input => CoreMIDI::Source.all, :output => CoreMIDI::Destination.all }.each do |type, devs|
|
14
21
|
puts ""
|
15
22
|
puts "select an #{type.to_s}..."
|
16
|
-
while
|
23
|
+
while @device[type].nil?
|
17
24
|
devs.each do |device|
|
18
25
|
puts "#{device.id}: #{device.name}"
|
19
26
|
end
|
20
27
|
selection = $stdin.gets.chomp
|
21
28
|
if selection != ""
|
22
29
|
selection = selection.to_i
|
23
|
-
|
24
|
-
puts "selected #{selection} for #{type.to_s}" unless
|
30
|
+
@device[type] = devs.find { |d| d.id == selection }
|
31
|
+
puts "selected #{selection} for #{type.to_s}" unless @device[type]
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
28
|
-
|
29
|
-
|
35
|
+
@device
|
36
|
+
end
|
37
|
+
|
30
38
|
def bytestrs_to_ints(arr)
|
31
39
|
data = arr.map { |m| m[:data] }.join
|
32
40
|
output = []
|
33
41
|
until (bytestr = data.slice!(0,2)).eql?("")
|
34
42
|
output << bytestr.hex
|
35
43
|
end
|
36
|
-
output
|
44
|
+
output
|
37
45
|
end
|
38
|
-
|
46
|
+
|
39
47
|
# some MIDI messages
|
40
48
|
VariousMIDIMessages = [
|
41
49
|
[0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7], # SysEx
|
@@ -45,14 +53,14 @@ module TestHelper
|
|
45
53
|
[0x90, 60, 100], # note on
|
46
54
|
[0x80, 100, 100] # note off
|
47
55
|
]
|
48
|
-
|
56
|
+
|
49
57
|
# some MIDI messages
|
50
58
|
VariousMIDIByteStrMessages = [
|
51
59
|
"F04110421240007F0041F7", # SysEx
|
52
60
|
"906440", # note on
|
53
61
|
"804340" # note off
|
54
62
|
]
|
55
|
-
|
63
|
+
|
56
64
|
end
|
57
65
|
|
58
66
|
TestHelper.select_devices
|
data/test/input_buffer_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "helper"
|
2
2
|
|
3
|
-
class InputBufferTest < Test
|
3
|
+
class InputBufferTest < Minitest::Test
|
4
4
|
|
5
5
|
context "CoreMIDI" do
|
6
6
|
|
@@ -16,8 +16,8 @@ class InputBufferTest < Test::Unit::TestCase
|
|
16
16
|
@received_arr = []
|
17
17
|
@pointer = 0
|
18
18
|
|
19
|
-
@output =
|
20
|
-
@input =
|
19
|
+
@output = TestHelper.device[:output].open
|
20
|
+
@input = TestHelper.device[:input].open
|
21
21
|
@input.buffer.clear
|
22
22
|
end
|
23
23
|
|
@@ -26,7 +26,7 @@ class InputBufferTest < Test::Unit::TestCase
|
|
26
26
|
@messages.each do |message|
|
27
27
|
puts "sending: #{message.inspect}"
|
28
28
|
@output.puts(message)
|
29
|
-
bytes += message
|
29
|
+
bytes += message
|
30
30
|
|
31
31
|
sleep(0.5)
|
32
32
|
|
data/test/io_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "helper"
|
2
2
|
|
3
|
-
class CoreMIDI::IOTest < Test
|
3
|
+
class CoreMIDI::IOTest < Minitest::Test
|
4
4
|
|
5
5
|
# ** these tests assume that TestOutput is connected to TestInput
|
6
6
|
context "CoreMIDI" do
|
@@ -21,8 +21,8 @@ class CoreMIDI::IOTest < Test::Unit::TestCase
|
|
21
21
|
end
|
22
22
|
|
23
23
|
should "do IO" do
|
24
|
-
|
25
|
-
|
24
|
+
TestHelper.device[:output].open do |output|
|
25
|
+
TestHelper.device[:input].open do |input|
|
26
26
|
|
27
27
|
input.buffer.clear
|
28
28
|
|
@@ -57,8 +57,8 @@ class CoreMIDI::IOTest < Test::Unit::TestCase
|
|
57
57
|
end
|
58
58
|
|
59
59
|
should "do IO" do
|
60
|
-
|
61
|
-
|
60
|
+
TestHelper.device[:output].open do |output|
|
61
|
+
TestHelper.device[:input].open do |input|
|
62
62
|
|
63
63
|
@messages.each do |msg|
|
64
64
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-coremidi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ari Russo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|