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.
@@ -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: