rtmidi 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }
@@ -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
+ };
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ require 'ffi'
2
+ require 'rtmidi/interface.rb'
3
+ require 'rtmidi/in.rb'
4
+ require 'rtmidi/out.rb'
@@ -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
@@ -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: