ffi-coremidi 0.2.0 → 0.2.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f0cd3edc0360a57ce8923b96a96f88e61b050ffd
4
+ data.tar.gz: 38f95b91e6ef5a5e34628dd56d024101062e7ed4
5
+ SHA512:
6
+ metadata.gz: 46c3ff9c2e946688b0b5f92cb10a0b5062fe90afedcfde912e1fc89b955774ea924da28b3bb01db123615ed93b4218938ddcb149ae55608373e810e451847ef5
7
+ data.tar.gz: 3e4ccf3a0c4362908c5273f71a11ec989d2abce5fc7f9eb5d3204ebf4f5405561aa331d74a7545d44f2a5555017c906cf1ce48da240b3ee5fda13d656d163fcc
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2011-2013 Ari Russo
1
+ Copyright 2011-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
@@ -2,7 +2,7 @@
2
2
 
3
3
  #### Realtime MIDI IO with Ruby for OSX
4
4
 
5
- This is a Ruby implementation of the Apple Core MIDI framework API.
5
+ This is a Ruby implementation of the [Apple Core MIDI framework API](https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CACoreMIDIRef/MIDIServices/).
6
6
 
7
7
  Note that in the interest of allowing people on other platforms to utilize your code, please consider using [UniMIDI](http://github.com/arirusso/unimidi). UniMIDI is a platform independent wrapper which implements this library with a similar API.
8
8
 
@@ -18,7 +18,7 @@ Note that in the interest of allowing people on other platforms to utilize your
18
18
 
19
19
  * [ffi](http://github.com/ffi/ffi)
20
20
 
21
- ### Install
21
+ ### Installation
22
22
 
23
23
  If you're using Bundler, add this line to your application's Gemfile:
24
24
 
@@ -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-2013 [Ari Russo](http://github.com/arirusso)
51
+ Copyright (c) 2011-2014 [Ari Russo](http://github.com/arirusso)
@@ -1,21 +1,22 @@
1
1
  # ffi-coremidi
2
+ #
2
3
  # Realtime MIDI IO with Ruby for OSX
3
- # (c)2011-2013 Ari Russo
4
+ # (c)2011-2014 Ari Russo
4
5
 
5
6
  # libs
6
- require 'ffi'
7
- require 'forwardable'
7
+ require "ffi"
8
+ require "forwardable"
8
9
 
9
10
  # modules
10
- require 'coremidi/endpoint'
11
- require 'coremidi/map'
11
+ require "coremidi/endpoint"
12
+ require "coremidi/map"
12
13
 
13
14
  # classes
14
- require 'coremidi/entity'
15
- require 'coremidi/device'
16
- require 'coremidi/source'
17
- require 'coremidi/destination'
15
+ require "coremidi/entity"
16
+ require "coremidi/device"
17
+ require "coremidi/source"
18
+ require "coremidi/destination"
18
19
 
19
20
  module CoreMIDI
20
- VERSION = "0.2.0"
21
+ VERSION = "0.2.1"
21
22
  end
@@ -19,6 +19,7 @@ module CoreMIDI
19
19
  until (str = data.slice!(0,2)).eql?("")
20
20
  output << str.hex
21
21
  end
22
+
22
23
  puts_bytes(*output)
23
24
  end
24
25
  alias_method :puts_bytestr, :puts_s
@@ -8,45 +8,51 @@ module CoreMIDI
8
8
  attr_reader :buffer
9
9
 
10
10
  #
11
- # returns an array of MIDI event hashes as such:
11
+ # An array of MIDI event hashes as such:
12
12
  # [
13
13
  # { :data => [144, 60, 100], :timestamp => 1024 },
14
14
  # { :data => [128, 60, 100], :timestamp => 1100 },
15
15
  # { :data => [144, 40, 120], :timestamp => 1200 }
16
16
  # ]
17
17
  #
18
- # the data is an array of Numeric bytes
19
- # the timestamp is the number of millis since this input was enabled
18
+ # The data is an array of Numeric bytes
19
+ # The timestamp is the number of millis since this input was enabled
20
20
  #
21
+ # @return [Array<Hash>]
21
22
  def gets
22
23
  until queued_messages?
24
+ # per https://github.com/arirusso/unimidi/issues/20#issuecomment-44761318
25
+ sleep(0.0001) # patch to prevent 100% CPU issue with some midi controllers
23
26
  end
24
- msgs = queued_messages
27
+ messages = queued_messages
25
28
  @pointer = @buffer.length
26
- msgs
29
+ messages
27
30
  end
28
31
  alias_method :read, :gets
29
32
 
30
- # same as gets but returns message data as string of hex digits as such:
33
+ # Same as Source#gets except that it returns message data as string of hex
34
+ # digits as such:
31
35
  # [
32
36
  # { :data => "904060", :timestamp => 904 },
33
37
  # { :data => "804060", :timestamp => 1150 },
34
38
  # { :data => "90447F", :timestamp => 1300 }
35
39
  # ]
36
40
  #
37
- #
41
+ # @return [Array<Hash>]
38
42
  def gets_s
39
- msgs = gets
40
- msgs.each { |msg| msg[:data] = numeric_bytes_to_hex_string(msg[:data]) }
41
- msgs
43
+ messages = gets
44
+ messages.each do |message|
45
+ message[:data] = numeric_bytes_to_hex_string(message[:data])
46
+ end
47
+ messages
42
48
  end
43
49
  alias_method :gets_bytestr, :gets_s
44
50
 
45
- # enable this the input for use; can be passed a block
51
+ # Enable this the input for use; can be passed a block
46
52
  def enable(options = {}, &block)
47
53
  @enabled = true
48
54
 
49
- unless block.nil?
55
+ if block_given?
50
56
  begin
51
57
  yield(self)
52
58
  ensure
@@ -70,6 +76,7 @@ module CoreMIDI
70
76
  #error = Map.MIDIEndpointDispose(@resource)
71
77
  #raise "MIDIEndpointDispose returned error code #{error}" unless error.zero?
72
78
  @enabled = false
79
+ true
73
80
  end
74
81
 
75
82
  # Shortcut to the first available input endpoint
@@ -140,12 +147,15 @@ module CoreMIDI
140
147
 
141
148
  # Timestamp for a received MIDI message
142
149
  def timestamp(now)
143
- ((now - @start_time) * 1000)
150
+ (now - @start_time) * 1000
144
151
  end
145
152
 
146
153
  # Give a message its timestamp and package it in a Hash
147
154
  def get_message_formatted(raw, time)
148
- { :data => raw, :timestamp => timestamp(time) }
155
+ {
156
+ :data => raw,
157
+ :timestamp => timestamp(time)
158
+ }
149
159
  end
150
160
 
151
161
  # Initialize a coremidi port for this endpoint
@@ -156,6 +166,7 @@ module CoreMIDI
156
166
  error = Map.MIDIInputPortCreate(@client, port_name, @callback, nil, handle_ptr)
157
167
  @handle = handle_ptr.read_pointer
158
168
  raise "MIDIInputPortCreate returned error code #{error}" unless error.zero?
169
+ true
159
170
  end
160
171
 
161
172
  # Initialize the MIDI message buffer
@@ -165,12 +176,18 @@ module CoreMIDI
165
176
  def @buffer.clear
166
177
  super
167
178
  @pointer = 0
168
- end
179
+ end
180
+ true
169
181
  end
170
182
 
171
183
  # Convert an array of numeric byes to a hex string (e.g. [0x90, 0x40, 0x40] becomes "904040")
172
184
  def numeric_bytes_to_hex_string(bytes)
173
- bytes.map { |b| s = b.to_s(16).upcase; b < 16 ? s = "0" + s : s; s }.join
185
+ string_bytes = bytes.map do |byte|
186
+ str = byte.to_s(16).upcase
187
+ str = "0" + str if byte < 16
188
+ str
189
+ end
190
+ string_bytes.join
174
191
  end
175
192
 
176
193
  end
@@ -1,10 +1,10 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  dir = File.dirname(File.expand_path(__FILE__))
4
- $LOAD_PATH.unshift dir + '/../lib'
2
+ $LOAD_PATH.unshift dir + "/../lib"
5
3
 
6
- require 'test/unit'
7
- require 'coremidi'
4
+ require "test/unit"
5
+ require "mocha/test_unit"
6
+ require "shoulda-context"
7
+ require "coremidi"
8
8
 
9
9
  module TestHelper
10
10
 
@@ -55,4 +55,4 @@ module TestHelper
55
55
 
56
56
  end
57
57
 
58
- TestHelper.select_devices
58
+ TestHelper.select_devices
@@ -1,6 +1,4 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'helper'
1
+ require "helper"
4
2
 
5
3
  class InputBufferTest < Test::Unit::TestCase
6
4
 
@@ -42,4 +40,4 @@ class InputBufferTest < Test::Unit::TestCase
42
40
  end
43
41
  end
44
42
 
45
- end
43
+ end
@@ -0,0 +1,90 @@
1
+ require 'helper'
2
+
3
+ class CoreMIDI::IOTest < Test::Unit::TestCase
4
+
5
+ # ** these tests assume that TestOutput is connected to TestInput
6
+ context "CoreMIDI" do
7
+
8
+ setup do
9
+ sleep(1)
10
+ end
11
+
12
+ context "full IO" do
13
+
14
+ context "using Arrays" do
15
+
16
+ setup do
17
+ @messages = TestHelper::VariousMIDIMessages
18
+ @messages_arr = @messages.inject { |a,b| a+b }.flatten
19
+ @received_arr = []
20
+ @pointer = 0
21
+ end
22
+
23
+ should "do IO" do
24
+ $test_device[:output].open do |output|
25
+ $test_device[:input].open do |input|
26
+
27
+ input.buffer.clear
28
+
29
+ @messages.each do |msg|
30
+
31
+ $>.puts "sending: " + msg.inspect
32
+
33
+ output.puts(msg)
34
+ sleep(1)
35
+ received = input.gets.map { |m| m[:data] }.flatten
36
+
37
+ $>.puts "received: " + received.inspect
38
+
39
+ assert_equal(@messages_arr.slice(@pointer, received.length), received)
40
+ @pointer += received.length
41
+ @received_arr += received
42
+ end
43
+ assert_equal(@messages_arr.length, @received_arr.length)
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ context "using byte Strings" do
51
+
52
+ setup do
53
+ @messages = TestHelper::VariousMIDIByteStrMessages
54
+ @messages_str = @messages.join
55
+ @received_str = ""
56
+ @pointer = 0
57
+ end
58
+
59
+ should "do IO" do
60
+ $test_device[:output].open do |output|
61
+ $test_device[:input].open do |input|
62
+
63
+ @messages.each do |msg|
64
+
65
+ $>.puts "sending: " + msg.inspect
66
+
67
+ output.puts(msg)
68
+ sleep(1)
69
+ received = input.gets_bytestr.map { |m| m[:data] }.flatten.join
70
+ $>.puts "received: " + received.inspect
71
+
72
+ assert_equal(@messages_str.slice(@pointer, received.length), received)
73
+ @pointer += received.length
74
+ @received_str += received
75
+ end
76
+ assert_equal(@messages_str, @received_str)
77
+
78
+ end
79
+ end
80
+
81
+
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
metadata CHANGED
@@ -1,73 +1,70 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-coremidi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ari Russo
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-08 00:00:00.000000000 Z
11
+ date: 2014-08-31 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: ffi
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.0'
30
- description: Realtime MIDI IO with Ruby for OSX
27
+ description: Perform realtime MIDI IO with Ruby for OSX
31
28
  email:
32
29
  - ari.russo@gmail.com
33
30
  executables: []
34
31
  extensions: []
35
32
  extra_rdoc_files: []
36
33
  files:
34
+ - LICENSE
35
+ - README.md
36
+ - lib/coremidi.rb
37
37
  - lib/coremidi/destination.rb
38
38
  - lib/coremidi/device.rb
39
39
  - lib/coremidi/endpoint.rb
40
40
  - lib/coremidi/entity.rb
41
41
  - lib/coremidi/map.rb
42
42
  - lib/coremidi/source.rb
43
- - lib/coremidi.rb
44
43
  - test/helper.rb
45
- - test/test_input_buffer.rb
46
- - test/test_io.rb
47
- - LICENSE
48
- - README.md
44
+ - test/input_buffer_test.rb
45
+ - test/io_test.rb
49
46
  homepage: http://github.com/arirusso/ffi-coremidi
50
- licenses: []
47
+ licenses:
48
+ - Apache 2.0
49
+ metadata: {}
51
50
  post_install_message:
52
51
  rdoc_options: []
53
52
  require_paths:
54
53
  - lib
55
54
  required_ruby_version: !ruby/object:Gem::Requirement
56
- none: false
57
55
  requirements:
58
- - - ! '>='
56
+ - - ">="
59
57
  - !ruby/object:Gem::Version
60
58
  version: '0'
61
59
  required_rubygems_version: !ruby/object:Gem::Requirement
62
- none: false
63
60
  requirements:
64
- - - ! '>='
61
+ - - ">="
65
62
  - !ruby/object:Gem::Version
66
63
  version: 1.3.6
67
64
  requirements: []
68
65
  rubyforge_project: ffi-coremidi
69
- rubygems_version: 1.8.25
66
+ rubygems_version: 2.2.2
70
67
  signing_key:
71
- specification_version: 3
68
+ specification_version: 4
72
69
  summary: Realtime MIDI IO with Ruby for OSX
73
70
  test_files: []
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'helper'
4
-
5
- class IoTest < Test::Unit::TestCase
6
-
7
- include CoreMIDI
8
- include TestHelper
9
-
10
- def test_full_io
11
- sleep(2)
12
- messages = VariousMIDIMessages
13
- messages_arr = messages.inject { |a,b| a+b }.flatten
14
- received_arr = []
15
- pointer = 0
16
- $test_device[:output].open do |output|
17
- $test_device[:input].open do |input|
18
-
19
- input.buffer.clear
20
-
21
- messages.each do |msg|
22
-
23
- $>.puts "sending: " + msg.inspect
24
-
25
- output.puts(msg)
26
- sleep(1)
27
- received = input.gets.map { |m| m[:data] }.flatten
28
-
29
- $>.puts "received: " + received.inspect
30
-
31
- assert_equal(messages_arr.slice(pointer, received.length), received)
32
-
33
- pointer += received.length
34
-
35
- received_arr += received
36
-
37
- end
38
-
39
- assert_equal(messages_arr.length, received_arr.length)
40
-
41
- end
42
- end
43
- end
44
-
45
- # ** this test assumes that TestOutput is connected to TestInput
46
- def test_full_io_bytestr
47
- sleep(2) # pause between tests
48
-
49
- messages = VariousMIDIByteStrMessages
50
- messages_str = messages.join
51
- received_str = ""
52
- pointer = 0
53
-
54
- $test_device[:output].open do |output|
55
- $test_device[:input].open do |input|
56
-
57
- input.buffer.clear
58
-
59
- messages.each do |msg|
60
-
61
- $>.puts "sending: " + msg.inspect
62
-
63
- output.puts_s(msg)
64
- sleep(1)
65
- received = input.gets_bytestr.map { |m| m[:data] }.flatten.join
66
- $>.puts "received: " + received.inspect
67
-
68
- assert_equal(messages_str.slice(pointer, received.length), received)
69
-
70
- pointer += received.length
71
-
72
- received_str += received
73
-
74
- end
75
-
76
- assert_equal(messages_str, received_str)
77
-
78
- end
79
- end
80
-
81
- end
82
-
83
- end