rtmidi 0.2.2 → 0.3
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/README.md +38 -11
- data/Rakefile +24 -7
- data/examples/list_ports.rb +2 -2
- data/examples/receive_any_message.rb +35 -0
- data/examples/receive_channel_message.rb +35 -0
- data/examples/send_any_message.rb +31 -0
- data/examples/send_channel_message.rb +34 -0
- data/ext/Rakefile +7 -93
- data/ext/ruby-rtmidi.cpp +24 -0
- data/ext/ruby-rtmidi.h +5 -0
- data/ext/ruby-rtmidi.o +0 -0
- data/ext/ruby-rtmidi.so +0 -0
- data/lib/rtmidi.rb +5 -0
- data/lib/rtmidi/build/compiler.rb +132 -0
- data/lib/rtmidi/build/system.rb +58 -0
- data/lib/rtmidi/in.rb +70 -19
- data/lib/rtmidi/interface.rb +11 -6
- data/lib/rtmidi/out.rb +35 -11
- data/spec/rtmidi/build/compiler_spec.rb +438 -0
- data/spec/rtmidi/build/system_spec.rb +130 -0
- data/spec/rtmidi/in_spec.rb +131 -0
- data/spec/rtmidi/out_spec.rb +87 -0
- data/spec/spec_helper.rb +12 -0
- metadata +27 -4
- data/examples/monitor_input.rb +0 -31
- data/examples/play_notes.rb +0 -28
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RtMidi::Interface
|
4
|
+
# Avoid method missing errors triggered by the at_exit cleanup code in RtMidi::In
|
5
|
+
def midiin_delete(rtmidi_ptr)
|
6
|
+
end
|
7
|
+
module_function :midiin_delete
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
describe RtMidi::In do
|
12
|
+
|
13
|
+
let(:midiin) { RtMidi::In.new }
|
14
|
+
let(:mock_rtmidiin) { :mock_rtmidiin }
|
15
|
+
let(:mock_input_ports) { {0 => 'first input', 1 => 'second input', 2 => 'third input'} }
|
16
|
+
|
17
|
+
before do
|
18
|
+
RtMidi::Interface.stub(:midiin_new).and_return mock_rtmidiin
|
19
|
+
|
20
|
+
RtMidi::Interface.stub(:midiin_delete).with(:mock_rtmidiin)
|
21
|
+
|
22
|
+
RtMidi::Interface.stub(:midiin_port_count).with(mock_rtmidiin).and_return mock_input_ports.size
|
23
|
+
|
24
|
+
RtMidi::Interface.stub(:midiin_port_name) do |rtmidi_ptr, port_index|
|
25
|
+
mock_input_ports[port_index] if rtmidi_ptr == mock_rtmidiin
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe '#port_count' do
|
31
|
+
it 'returns the number of ports available' do
|
32
|
+
midiin.port_count.should == mock_input_ports.size
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#port_name' do
|
37
|
+
it 'returns the name of the port with the given index' do
|
38
|
+
for index,name in mock_input_ports
|
39
|
+
midiin.port_name(index).should == name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns nil for invalid port indexes' do
|
44
|
+
midiin.port_name(mock_input_ports.size).should be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#port_names' do
|
49
|
+
it 'returns the names of the available ports' do
|
50
|
+
midiin.port_names.should == mock_input_ports.values
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#open_port' do
|
55
|
+
it 'calls RtMidi::Interface.midiin_open_port' do
|
56
|
+
RtMidi::Interface.should_receive(:midiin_open_port).with(mock_rtmidiin, 1)
|
57
|
+
midiin.open_port(1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#close_port' do
|
62
|
+
it 'calls RtMidi::Interface.midiin_close_port' do
|
63
|
+
RtMidi::Interface.should_receive(:midiin_close_port).with(mock_rtmidiin)
|
64
|
+
midiin.close_port
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#receive_channel_message' do
|
69
|
+
it 'sets up a callback that receives 3 ints' do
|
70
|
+
RtMidi::Interface.stub(:midiin_set_callback) do |rtmidi_ptr, callback|
|
71
|
+
rtmidi_ptr.should be mock_rtmidiin
|
72
|
+
callback.call(1,2,3)
|
73
|
+
end
|
74
|
+
|
75
|
+
RtMidi::Interface.should_receive(:midiin_ignore_types).with(mock_rtmidiin, true, true, true)
|
76
|
+
RtMidi::Interface.should_receive(:midiin_set_callback)
|
77
|
+
|
78
|
+
received_bytes = []
|
79
|
+
midiin.receive_channel_message do |byte1, byte2, byte3|
|
80
|
+
received_bytes << byte1
|
81
|
+
received_bytes << byte2
|
82
|
+
received_bytes << byte3
|
83
|
+
end
|
84
|
+
received_bytes.should == [1,2,3]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#receive_message' do
|
89
|
+
it 'sets up a callback to receive arbitrary byte lists' do
|
90
|
+
RtMidi::Interface.stub(:midiin_set_varargs_callback) do |rtmidi_ptr, callback|
|
91
|
+
rtmidi_ptr.should be mock_rtmidiin
|
92
|
+
bytes = [1,2,3,4]
|
93
|
+
FFI::MemoryPointer.new(:int, bytes.length) do |p|
|
94
|
+
p.write_array_of_uchar(bytes)
|
95
|
+
callback.call(p, 4)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
RtMidi::Interface.should_receive(:midiin_ignore_types).with(mock_rtmidiin, false, false, false)
|
100
|
+
RtMidi::Interface.should_receive(:midiin_set_varargs_callback)
|
101
|
+
|
102
|
+
received_bytes = nil
|
103
|
+
midiin.receive_message do |*bytes|
|
104
|
+
received_bytes = bytes
|
105
|
+
end
|
106
|
+
|
107
|
+
received_bytes.should == [1,2,3,4]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# TODO: test behavior when calling receive* multiple times
|
112
|
+
|
113
|
+
describe '#stop_receiving' do
|
114
|
+
it 'does nothing if no receive callback was setup' do
|
115
|
+
midiin.stop_receiving
|
116
|
+
# that's it, should have no errors, since we didn't setup stubs or RtMidi::Interface.should_receive expectations
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'calls RtMidi::Interface.midiin_cancel_callback if a receive callback was setup' do
|
120
|
+
RtMidi::Interface.should_receive(:midiin_ignore_types)
|
121
|
+
RtMidi::Interface.should_receive(:midiin_set_varargs_callback)
|
122
|
+
|
123
|
+
midiin.receive_message{|*bytes|}
|
124
|
+
|
125
|
+
RtMidi::Interface.should_receive(:midiin_cancel_callback)
|
126
|
+
|
127
|
+
midiin.stop_receiving
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RtMidi::Interface
|
4
|
+
# Avoid method missing errors triggered by the at_exit cleanup code in RtMidi::Out
|
5
|
+
def midiout_delete(rtmidi_ptr)
|
6
|
+
end
|
7
|
+
module_function :midiout_delete
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
describe RtMidi::Out do
|
12
|
+
|
13
|
+
let(:midiout) { RtMidi::Out.new }
|
14
|
+
let(:mock_rtmidiout) { :mock_rtmidiout }
|
15
|
+
let(:mock_output_ports) { {0 => 'first output', 1 => 'second output', 2 => 'third output'} }
|
16
|
+
|
17
|
+
before do
|
18
|
+
RtMidi::Interface.stub(:midiout_new).and_return mock_rtmidiout
|
19
|
+
|
20
|
+
RtMidi::Interface.stub(:midiout_delete).with(:mock_rtmidiout)
|
21
|
+
|
22
|
+
RtMidi::Interface.stub(:midiout_port_count).with(mock_rtmidiout).and_return mock_output_ports.size
|
23
|
+
|
24
|
+
RtMidi::Interface.stub(:midiout_port_name) do |rtmidi_ptr, port_index|
|
25
|
+
mock_output_ports[port_index] if rtmidi_ptr == mock_rtmidiout
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe '#port_count' do
|
31
|
+
it 'returns the number of ports available' do
|
32
|
+
midiout.port_count.should == mock_output_ports.size
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#port_name' do
|
37
|
+
it 'returns the name of the port with the given index' do
|
38
|
+
for index,name in mock_output_ports
|
39
|
+
midiout.port_name(index).should == name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns nil for invalid port indexes' do
|
44
|
+
midiout.port_name(mock_output_ports.size).should be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#port_names' do
|
49
|
+
it 'returns the names of the available ports' do
|
50
|
+
midiout.port_names.should == mock_output_ports.values
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#open_port' do
|
55
|
+
it 'calls RtMidi::Interface.midiout_open_port' do
|
56
|
+
RtMidi::Interface.should_receive(:midiout_open_port).with(mock_rtmidiout, 1)
|
57
|
+
midiout.open_port(1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#close_port' do
|
62
|
+
it 'calls RtMidi::Interface.midiout_close_port' do
|
63
|
+
RtMidi::Interface.should_receive(:midiout_close_port).with(mock_rtmidiout)
|
64
|
+
midiout.close_port
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#send_channel_message' do
|
69
|
+
it 'calls RtMidi::Interface.midiout_send_message with 3 ints' do
|
70
|
+
RtMidi::Interface.should_receive(:midiout_send_message).with(mock_rtmidiout, 1, 2, 3)
|
71
|
+
midiout.send_channel_message(1, 2, 3)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#send_message' do
|
76
|
+
it 'calls RtMidi::Interface.midiout_send_bytes with an int array' do
|
77
|
+
RtMidi::Interface.stub(:midiout_send_bytes) do |rtmidi_ptr, bytes|
|
78
|
+
rtmidi_ptr.should be mock_rtmidiout
|
79
|
+
bytes.should be_a FFI::MemoryPointer
|
80
|
+
bytes.read_array_of_int(4).should == [1,2,3,4]
|
81
|
+
end
|
82
|
+
RtMidi::Interface.should_receive(:midiout_send_bytes)
|
83
|
+
midiout.send_message(1, 2, 3, 4)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtmidi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Murray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.14'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.14'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: yard
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,6 +79,8 @@ files:
|
|
65
79
|
- README.md
|
66
80
|
- LICENSE.txt
|
67
81
|
- .yardopts
|
82
|
+
- lib/rtmidi/build/compiler.rb
|
83
|
+
- lib/rtmidi/build/system.rb
|
68
84
|
- lib/rtmidi/in.rb
|
69
85
|
- lib/rtmidi/interface.rb
|
70
86
|
- lib/rtmidi/out.rb
|
@@ -81,8 +97,15 @@ files:
|
|
81
97
|
- ext/ruby-rtmidi.o
|
82
98
|
- ext/ruby-rtmidi.so
|
83
99
|
- examples/list_ports.rb
|
84
|
-
- examples/
|
85
|
-
- examples/
|
100
|
+
- examples/receive_any_message.rb
|
101
|
+
- examples/receive_channel_message.rb
|
102
|
+
- examples/send_any_message.rb
|
103
|
+
- examples/send_channel_message.rb
|
104
|
+
- spec/rtmidi/build/compiler_spec.rb
|
105
|
+
- spec/rtmidi/build/system_spec.rb
|
106
|
+
- spec/rtmidi/in_spec.rb
|
107
|
+
- spec/rtmidi/out_spec.rb
|
108
|
+
- spec/spec_helper.rb
|
86
109
|
homepage: http://github.com/adamjmurray/ruby-rtmidi
|
87
110
|
licenses:
|
88
111
|
- BSD
|
data/examples/monitor_input.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require "rtmidi"
|
2
|
-
|
3
|
-
midiin = RtMidi::In.new
|
4
|
-
|
5
|
-
puts "Available MIDI input ports"
|
6
|
-
midiin.port_names.each_with_index{|name,index| puts " ##{index+1}: #{name}" }
|
7
|
-
|
8
|
-
def select_port(midiin)
|
9
|
-
print "Select a port number: "
|
10
|
-
if (port_number = gets) =~ /^\d+$/
|
11
|
-
port_index = port_number.to_i - 1
|
12
|
-
if (0...midiin.port_count).include? port_index
|
13
|
-
return port_index
|
14
|
-
end
|
15
|
-
end
|
16
|
-
puts "Invalid port number"
|
17
|
-
nil
|
18
|
-
end
|
19
|
-
|
20
|
-
port_index = select_port(midiin) until port_index
|
21
|
-
|
22
|
-
midiin.set_callback do |byte1, byte2, byte3|
|
23
|
-
puts "#{byte1} #{byte2} #{byte3}"
|
24
|
-
end
|
25
|
-
|
26
|
-
puts "Listening for MIDI messages..."
|
27
|
-
puts "Ctrl+C to exit"
|
28
|
-
|
29
|
-
midiin.open_port(port_index)
|
30
|
-
|
31
|
-
sleep # prevent Ruby from exiting immediately
|
data/examples/play_notes.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require "rtmidi"
|
2
|
-
|
3
|
-
midiout = RtMidi::Out.new
|
4
|
-
|
5
|
-
puts "Available MIDI output ports"
|
6
|
-
midiout.port_names.each_with_index{|name,index| puts " ##{index+1}: #{name}" }
|
7
|
-
|
8
|
-
def select_port(midiout)
|
9
|
-
print "Select a port number: "
|
10
|
-
if (port_number = gets) =~ /^\d+$/
|
11
|
-
port_index = port_number.to_i - 1
|
12
|
-
if (0...midiout.port_count).include? port_index
|
13
|
-
return port_index
|
14
|
-
end
|
15
|
-
end
|
16
|
-
puts "Invalid port number"
|
17
|
-
nil
|
18
|
-
end
|
19
|
-
|
20
|
-
port_index = select_port(midiout) until port_index
|
21
|
-
midiout.open_port(port_index)
|
22
|
-
|
23
|
-
for pitch in [60, 62, 64, 65, 67]
|
24
|
-
midiout.send_message(0x90, pitch, 127) # note on
|
25
|
-
sleep 0.5
|
26
|
-
midiout.send_message(0x90, pitch, 0) # note off
|
27
|
-
end
|
28
|
-
sleep 0.5
|