rtmidi 0.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.
- checksums.yaml +15 -0
- data/.yardopts +7 -0
- data/DEV_NOTES.md +13 -0
- data/LICENSE.txt +46 -0
- data/README.md +82 -0
- data/Rakefile +10 -0
- data/examples/list_ports.rb +15 -0
- data/examples/monitor_input.rb +31 -0
- data/examples/play_notes.rb +28 -0
- data/ext/Rakefile +57 -0
- data/ext/rtmidi-2.0.1/RtError.h +60 -0
- data/ext/rtmidi-2.0.1/RtMidi.cpp +3747 -0
- data/ext/rtmidi-2.0.1/RtMidi.h +675 -0
- data/ext/rtmidi-2.0.1/RtMidi.o +0 -0
- data/ext/rtmidi-2.0.1/include/ks.h +3577 -0
- data/ext/rtmidi-2.0.1/include/ksmedia.h +4824 -0
- data/ext/ruby-rtmidi.cpp +108 -0
- data/ext/ruby-rtmidi.h +44 -0
- data/ext/ruby-rtmidi.o +0 -0
- data/ext/ruby-rtmidi.so +0 -0
- data/lib/rtmidi.rb +4 -0
- data/lib/rtmidi/in.rb +76 -0
- data/lib/rtmidi/interface.rb +67 -0
- data/lib/rtmidi/out.rb +59 -0
- metadata +85 -0
data/ext/ruby-rtmidi.cpp
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
#include "RtMidi.h"
|
2
|
+
#include "RtError.h"
|
3
|
+
#include <vector>
|
4
|
+
#include <iostream> // TODO: can probably stop including this later when done debugging
|
5
|
+
|
6
|
+
#include "ruby-rtmidi.h"
|
7
|
+
|
8
|
+
|
9
|
+
//================================================
|
10
|
+
// INPUT
|
11
|
+
|
12
|
+
rtmidi_ptr midiin_new() {
|
13
|
+
return static_cast<void *>(new RtMidiIn());
|
14
|
+
}
|
15
|
+
|
16
|
+
void midiin_delete(rtmidi_ptr p) {
|
17
|
+
delete static_cast<RtMidiIn *>(p);
|
18
|
+
}
|
19
|
+
|
20
|
+
int midiin_port_count(rtmidi_ptr p) {
|
21
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
22
|
+
return midiin->getPortCount();
|
23
|
+
}
|
24
|
+
|
25
|
+
const char* midiin_port_name(rtmidi_ptr p, int port_index) {
|
26
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
27
|
+
return midiin->getPortName(port_index).c_str(); // getPortName returns a std::string, use c_str() to be convert to char*
|
28
|
+
}
|
29
|
+
|
30
|
+
void midiin_open_port(rtmidi_ptr p, int port_index) {
|
31
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
32
|
+
midiin->openPort(port_index);
|
33
|
+
}
|
34
|
+
|
35
|
+
void midiin_close_port(rtmidi_ptr p) {
|
36
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
37
|
+
midiin->closePort();
|
38
|
+
}
|
39
|
+
|
40
|
+
void midiin_ignore_types(rtmidi_ptr p, bool sysex, bool timing, bool active_sensing) {
|
41
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
42
|
+
midiin->ignoreTypes(sysex, timing, active_sensing);
|
43
|
+
}
|
44
|
+
|
45
|
+
void midiin_callback_proxy( double deltatime, std::vector< unsigned char > *message, void *userData )
|
46
|
+
{
|
47
|
+
unsigned int byte_count = message->size();
|
48
|
+
// for ( unsigned int i=0; i<byte_count; i++ )
|
49
|
+
// std::cout << "Byte " << i << " = " << (int)message->at(i) << ", ";
|
50
|
+
// if ( byte_count > 0 )
|
51
|
+
// std::cout << "stamp = " << deltatime << std::endl; # TODO: do we care about the deltatime?
|
52
|
+
int byte1 = 0, byte2 = 0, byte3 = 0;
|
53
|
+
if(byte_count > 0) byte1 = (int)message->at(0);
|
54
|
+
if(byte_count > 1) byte2 = (int)message->at(1);
|
55
|
+
if(byte_count > 2) byte3 = (int)message->at(2);
|
56
|
+
((rtmidi_callback)userData)(byte1, byte2, byte3);
|
57
|
+
}
|
58
|
+
|
59
|
+
void midiin_set_callback(rtmidi_ptr p, rtmidi_callback callback) {
|
60
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
61
|
+
midiin->setCallback(midiin_callback_proxy, (void *)callback);
|
62
|
+
}
|
63
|
+
|
64
|
+
void midiin_cancel_callback(rtmidi_ptr p) {
|
65
|
+
RtMidiIn *midiin = static_cast<RtMidiIn *>(p);
|
66
|
+
midiin->cancelCallback();
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
//================================================
|
71
|
+
// OUTPUT
|
72
|
+
|
73
|
+
rtmidi_ptr midiout_new() {
|
74
|
+
return static_cast<void *>(new RtMidiOut());
|
75
|
+
}
|
76
|
+
|
77
|
+
void midiout_delete(rtmidi_ptr p) {
|
78
|
+
delete static_cast<RtMidiOut *>(p);
|
79
|
+
}
|
80
|
+
|
81
|
+
int midiout_port_count(rtmidi_ptr p) {
|
82
|
+
RtMidiOut *midiout = static_cast<RtMidiOut *>(p);
|
83
|
+
return midiout->getPortCount();
|
84
|
+
}
|
85
|
+
|
86
|
+
const char* midiout_port_name(rtmidi_ptr p, int port_index) {
|
87
|
+
RtMidiOut *midiout = static_cast<RtMidiOut *>(p);
|
88
|
+
return midiout->getPortName(port_index).c_str(); // getPortName returns a std::string, use c_str() to be convert to char*
|
89
|
+
}
|
90
|
+
|
91
|
+
void midiout_open_port(rtmidi_ptr p, int port_index) {
|
92
|
+
RtMidiOut *midiout = static_cast<RtMidiOut *>(p);
|
93
|
+
midiout->openPort(port_index);
|
94
|
+
}
|
95
|
+
|
96
|
+
void midiout_close_port(rtmidi_ptr p) {
|
97
|
+
RtMidiOut *midiout = static_cast<RtMidiOut *>(p);
|
98
|
+
midiout->closePort();
|
99
|
+
}
|
100
|
+
|
101
|
+
void midiout_send_message(rtmidi_ptr p, int byte1, int byte2, int byte3) {
|
102
|
+
RtMidiOut *midiout = static_cast<RtMidiOut *>(p);
|
103
|
+
static std::vector<unsigned char> message(3); // static so we don't keep constructing and destroying objects
|
104
|
+
message[0] = byte1;
|
105
|
+
message[1] = byte2;
|
106
|
+
message[2] = byte3;
|
107
|
+
midiout->sendMessage(&message);
|
108
|
+
}
|
data/ext/ruby-rtmidi.h
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
extern "C"
|
2
|
+
{
|
3
|
+
typedef void* rtmidi_ptr;
|
4
|
+
typedef void (*rtmidi_callback)(int byte1, int byte2, int byte3);
|
5
|
+
|
6
|
+
//================================================
|
7
|
+
// INPUT
|
8
|
+
|
9
|
+
rtmidi_ptr midiin_new();
|
10
|
+
|
11
|
+
void midiin_delete(rtmidi_ptr midiin);
|
12
|
+
|
13
|
+
int midiin_port_count(rtmidi_ptr midiin);
|
14
|
+
|
15
|
+
const char* midiin_port_name(rtmidi_ptr midiin, int port_index);
|
16
|
+
|
17
|
+
void midiin_open_port(rtmidi_ptr p, int port_index);
|
18
|
+
|
19
|
+
void midiin_close_port(rtmidi_ptr p);
|
20
|
+
|
21
|
+
void midiin_ignore_types(rtmidi_ptr p, bool sysex, bool timing, bool active_sensing);
|
22
|
+
|
23
|
+
void midiin_set_callback(rtmidi_ptr p, rtmidi_callback callback);
|
24
|
+
|
25
|
+
void midiin_cancel_callback(rtmidi_ptr p);
|
26
|
+
|
27
|
+
|
28
|
+
//================================================
|
29
|
+
// OUTPUT
|
30
|
+
|
31
|
+
rtmidi_ptr midiout_new();
|
32
|
+
|
33
|
+
void midiout_delete(rtmidi_ptr midiout);
|
34
|
+
|
35
|
+
int midiout_port_count(rtmidi_ptr midiout);
|
36
|
+
|
37
|
+
const char* midiout_port_name(rtmidi_ptr midiout, int port_index);
|
38
|
+
|
39
|
+
void midiout_open_port(rtmidi_ptr p, int port_index);
|
40
|
+
|
41
|
+
void midiout_close_port(rtmidi_ptr p);
|
42
|
+
|
43
|
+
void midiout_send_message(rtmidi_ptr p, int byte1, int byte2, int byte3);
|
44
|
+
};
|
data/ext/ruby-rtmidi.o
ADDED
Binary file
|
data/ext/ruby-rtmidi.so
ADDED
Binary file
|
data/lib/rtmidi.rb
ADDED
data/lib/rtmidi/in.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module RtMidi
|
2
|
+
|
3
|
+
# Ruby representation of a RtMidiIn C++ object
|
4
|
+
# @see Out
|
5
|
+
class In
|
6
|
+
|
7
|
+
# Create a new RtMidiIn wrapper object.
|
8
|
+
def initialize
|
9
|
+
@midiin = Interface::midiin_new()
|
10
|
+
at_exit{ Interface::midiin_delete @midiin }
|
11
|
+
end
|
12
|
+
|
13
|
+
# The number of MIDI input ports available.
|
14
|
+
def port_count
|
15
|
+
@port_count ||= Interface::midiin_port_count(@midiin)
|
16
|
+
end
|
17
|
+
|
18
|
+
# The name of the MIDI input port at the given index.
|
19
|
+
# @see #port_names
|
20
|
+
def port_name(index)
|
21
|
+
port_names[index]
|
22
|
+
end
|
23
|
+
|
24
|
+
# The list of all MIDI input port names.
|
25
|
+
#
|
26
|
+
# The index of a port in this list is the index to be passed to {#port_name} and {#open_port}.
|
27
|
+
#
|
28
|
+
# @see #port_name
|
29
|
+
# @see #open_port
|
30
|
+
def port_names
|
31
|
+
@port_namess ||= (
|
32
|
+
names = []
|
33
|
+
port_count.times{|i| names << Interface::midiin_port_name(@midiin, i) }
|
34
|
+
names
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Open the MIDI input port at the given index.
|
39
|
+
# @see #port_names
|
40
|
+
def open_port(index)
|
41
|
+
Interface::midiin_open_port(@midiin, index)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Close all opened ports.
|
45
|
+
def close_ports()
|
46
|
+
Interface::midiin_close_port(@midiin)
|
47
|
+
end
|
48
|
+
|
49
|
+
# TODO: enable sysex listening by hooking up to midiin_ignore_types
|
50
|
+
# but that will require a more flexible callback interface.
|
51
|
+
|
52
|
+
# Setup a callback block to handle incoming MIDI channel messages from opened ports.
|
53
|
+
#
|
54
|
+
# The block should receive 3 bytes (Ruby integers)
|
55
|
+
#
|
56
|
+
# All messages are assumed to have 3 bytes.
|
57
|
+
# Some channel messages only have 2 bytes in which case the 3rd byte is 0.
|
58
|
+
# @example
|
59
|
+
# midiin.set_callback do |byte1, byte2, byte3|
|
60
|
+
# puts "#{byte1} #{byte2} #{byte3}"
|
61
|
+
# end
|
62
|
+
# @see #open_port
|
63
|
+
# @see #cancel_callback
|
64
|
+
def set_callback &callback
|
65
|
+
Interface::midiin_set_callback(@midiin, callback)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Cancel previously registered callbacks.
|
69
|
+
# @see #set_callback
|
70
|
+
def cancel_callback
|
71
|
+
Interface::midiin_cancel_callback(@midiin)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module RtMidi
|
2
|
+
|
3
|
+
# The interface to RtMidi C++ code
|
4
|
+
# @see RtMidi::In
|
5
|
+
# @see RtMidi::Out
|
6
|
+
module Interface
|
7
|
+
extend FFI::Library
|
8
|
+
ffi_lib "ext/ruby-rtmidi.so"
|
9
|
+
|
10
|
+
#####################################
|
11
|
+
# INPUT
|
12
|
+
|
13
|
+
# rtmidi_ptr create_rtmidiin();
|
14
|
+
attach_function :midiin_new, [], :pointer
|
15
|
+
|
16
|
+
# void delete_midiin(rtmidi_ptr midiin);
|
17
|
+
attach_function :midiin_delete, [:pointer], :void
|
18
|
+
|
19
|
+
# int midiin_port_count(rtmidi_ptr midiin);
|
20
|
+
attach_function :midiin_port_count, [:pointer], :int
|
21
|
+
|
22
|
+
# const char * midiin_port_name(rtmidi_ptr midiin, int port_index);
|
23
|
+
attach_function :midiin_port_name, [:pointer, :int], :string
|
24
|
+
|
25
|
+
# void midiin_open_port(rtmidi_ptr p, int port_index);
|
26
|
+
attach_function :midiin_open_port, [:pointer, :int], :void
|
27
|
+
|
28
|
+
# void midiin_close_port(rtmidi_ptr p, int port_index);
|
29
|
+
attach_function :midiin_close_port, [:pointer], :void
|
30
|
+
|
31
|
+
# void midiin_ignore_types(rtmidi_ptr p, bool sysex, bool timing, bool active_sensing);
|
32
|
+
attach_function :midiin_ignore_types, [:pointer, :bool, :bool, :bool], :void
|
33
|
+
|
34
|
+
# void midiin_set_callback(rtmidi_ptr p, rtmidi_callback callback);
|
35
|
+
callback :rtmidi_callback, [:int, :int, :int], :void
|
36
|
+
attach_function :midiin_set_callback, [:pointer, :rtmidi_callback], :void
|
37
|
+
|
38
|
+
# void midiin_cancel_callback(rtmidi_ptr p);
|
39
|
+
attach_function :midiin_cancel_callback, [:pointer], :void
|
40
|
+
|
41
|
+
|
42
|
+
#####################################
|
43
|
+
# OUTPUT
|
44
|
+
|
45
|
+
# rtmidi_ptr new_midiout();
|
46
|
+
attach_function :midiout_new, [], :pointer
|
47
|
+
|
48
|
+
# void delete_midiout(rtmidi_ptr midiout);
|
49
|
+
attach_function :midiout_delete, [:pointer], :void
|
50
|
+
|
51
|
+
# int midiout_port_count(rtmidi_ptr midiout);
|
52
|
+
attach_function :midiout_port_count, [:pointer], :int
|
53
|
+
|
54
|
+
# const char * midiout_port_name(rtmidi_ptr midiout, int port_index);
|
55
|
+
attach_function :midiout_port_name, [:pointer, :int], :string
|
56
|
+
|
57
|
+
# void midiout_open_port(rtmidi_ptr p, int port_index);
|
58
|
+
attach_function :midiout_open_port, [:pointer, :int], :void
|
59
|
+
|
60
|
+
# void midiout_close_port(rtmidi_ptr p);
|
61
|
+
attach_function :midiout_close_port, [:pointer], :void
|
62
|
+
|
63
|
+
# void midiout_message(rtmidi_ptr p, int byte1, int byte2, int byte3);
|
64
|
+
attach_function :midiout_send_message, [:pointer, :int, :int, :int], :void
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/lib/rtmidi/out.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module RtMidi
|
2
|
+
|
3
|
+
# Ruby representation of a RtMidiOut C++ object
|
4
|
+
# @see In
|
5
|
+
class Out
|
6
|
+
|
7
|
+
# Create a new RtMidiOut wrapper object.
|
8
|
+
def initialize
|
9
|
+
@midiout = Interface::midiout_new()
|
10
|
+
at_exit{ Interface::midiout_delete @midiout }
|
11
|
+
end
|
12
|
+
|
13
|
+
# The number of MIDI output ports available.
|
14
|
+
def port_count
|
15
|
+
@port_count ||= Interface::midiout_port_count(@midiout)
|
16
|
+
end
|
17
|
+
|
18
|
+
# The name of the MIDI output port at the given index.
|
19
|
+
# @see #port_names
|
20
|
+
def port_name(index)
|
21
|
+
port_names[index]
|
22
|
+
end
|
23
|
+
|
24
|
+
# The list of all MIDI output port names.
|
25
|
+
#
|
26
|
+
# The index of a port in this list is the index to be passed to {#port_name} and {#open_port}.
|
27
|
+
#
|
28
|
+
# @see #port_name
|
29
|
+
# @see #open_port
|
30
|
+
def port_names
|
31
|
+
@port_namess ||= (
|
32
|
+
names = []
|
33
|
+
port_count.times{|i| names << Interface::midiout_port_name(@midiout, i) }
|
34
|
+
names
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Open the MIDI output port at the given index.
|
39
|
+
# @see #port_names
|
40
|
+
def open_port(index)
|
41
|
+
Interface::midiout_open_port(@midiout, index)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Close all opened ports.
|
45
|
+
def close_ports()
|
46
|
+
Interface::midiout_close_port(@midiout)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Send a 3-byte MIDI channel message to the opened port.
|
50
|
+
#
|
51
|
+
# Some channel messages only have 2 bytes in which case the 3rd byte is ignored.
|
52
|
+
# @see #open_port
|
53
|
+
def send_message(byte1, byte2, byte3=0)
|
54
|
+
Interface::midiout_send_message(@midiout, byte1, byte2, byte3)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rtmidi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Murray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
description: Ruby wrapper for RtMidi, a cross-platform C++ library for realtime MIDI
|
28
|
+
input and output.
|
29
|
+
email: adam@compusition.com
|
30
|
+
executables: []
|
31
|
+
extensions:
|
32
|
+
- ext/Rakefile
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- Rakefile
|
36
|
+
- DEV_NOTES.md
|
37
|
+
- README.md
|
38
|
+
- LICENSE.txt
|
39
|
+
- .yardopts
|
40
|
+
- lib/rtmidi/in.rb
|
41
|
+
- lib/rtmidi/interface.rb
|
42
|
+
- lib/rtmidi/out.rb
|
43
|
+
- lib/rtmidi.rb
|
44
|
+
- ext/Rakefile
|
45
|
+
- ext/rtmidi-2.0.1/include/ks.h
|
46
|
+
- ext/rtmidi-2.0.1/include/ksmedia.h
|
47
|
+
- ext/rtmidi-2.0.1/RtError.h
|
48
|
+
- ext/rtmidi-2.0.1/RtMidi.cpp
|
49
|
+
- ext/rtmidi-2.0.1/RtMidi.h
|
50
|
+
- ext/rtmidi-2.0.1/RtMidi.o
|
51
|
+
- ext/ruby-rtmidi.cpp
|
52
|
+
- ext/ruby-rtmidi.h
|
53
|
+
- ext/ruby-rtmidi.o
|
54
|
+
- ext/ruby-rtmidi.so
|
55
|
+
- examples/list_ports.rb
|
56
|
+
- examples/monitor_input.rb
|
57
|
+
- examples/play_notes.rb
|
58
|
+
homepage: http://github.com/adamjmurray/ruby-rtmidi
|
59
|
+
licenses:
|
60
|
+
- BSD
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements:
|
77
|
+
- gcc
|
78
|
+
- g++
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.0.6
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Ruby-RtMidi
|
84
|
+
test_files: []
|
85
|
+
has_rdoc:
|