Skip to content

Commit a5c375c

Browse files
committed
Add C API.
1 parent 28321c0 commit a5c375c

File tree

4 files changed

+254
-1
lines changed

4 files changed

+254
-1
lines changed

Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ lib_LTLIBRARIES = %D%/librtmidi.la
22
%C%_librtmidi_la_LDFLAGS = -no-undefined
33
%C%_librtmidi_la_SOURCES = \
44
%D%/RtMidi.cpp \
5-
%D%/RtMidi.h
5+
%D%/RtMidi.h \
6+
%D%/rtmidi_c.cpp \
7+
%D%/rtmidi_c.h

msw/rtmidilib.vcproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@
151151
RelativePath="..\RtMidi.cpp"
152152
>
153153
</File>
154+
<File
155+
RelativePath="..\rtmidi_c.cpp"
156+
>
157+
</File>
154158
</Filter>
155159
<Filter
156160
Name="Header Files"
@@ -165,6 +169,10 @@
165169
RelativePath="..\RtMidi.h"
166170
>
167171
</File>
172+
<File
173+
RelativePath="..\rtmidi_c.h"
174+
>
175+
</File>
168176
</Filter>
169177
<Filter
170178
Name="Resource Files"

rtmidi_c.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#include <string.h>
2+
#include <stdlib.h>
3+
#include "rtmidi_c.h"
4+
#include "RtMidi.h"
5+
6+
/* misc */
7+
int rtmidi_sizeof_rtmidi_api ()
8+
{
9+
return sizeof (RtMidiApi);
10+
}
11+
12+
/* RtMidi API */
13+
int rtmidi_get_compiled_api (enum RtMidiApi **apis) // return length for NULL argument.
14+
{
15+
if (!apis || !(*apis)) {
16+
std::vector<RtMidi::Api> *v = new std::vector<RtMidi::Api> ();
17+
try {
18+
RtMidi::getCompiledApi (*v);
19+
int size = v->size ();
20+
delete v;
21+
return size;
22+
} catch (...) {
23+
return -1;
24+
}
25+
} else {
26+
try {
27+
std::vector<RtMidi::Api> *v = new std::vector<RtMidi::Api> ();
28+
RtMidi::getCompiledApi (*v);
29+
for (unsigned int i = 0; i < v->size (); i++)
30+
(*apis) [i] = (RtMidiApi) v->at (i);
31+
delete v;
32+
return 0;
33+
} catch (...) {
34+
return -1;
35+
}
36+
}
37+
}
38+
39+
void rtmidi_error (MidiApi *api, enum RtMidiErrorType type, const char* errorString)
40+
{
41+
std::string msg = errorString;
42+
api->error ((RtMidiError::Type) type, msg);
43+
}
44+
45+
void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *portName)
46+
{
47+
std::string name = portName;
48+
((RtMidi*) device)->openPort (portNumber, name);
49+
}
50+
51+
void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName)
52+
{
53+
std::string name = portName;
54+
((RtMidi*) device)->openVirtualPort (name);
55+
}
56+
57+
void rtmidi_close_port (RtMidiPtr device)
58+
{
59+
((RtMidi*) device)->closePort ();
60+
}
61+
62+
unsigned int rtmidi_get_port_count (RtMidiPtr device)
63+
{
64+
return ((RtMidi*) device)->getPortCount ();
65+
}
66+
67+
const char* rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber)
68+
{
69+
std::string name = ((RtMidi*) device)->getPortName (portNumber);
70+
return name.c_str ();
71+
}
72+
73+
/* RtMidiIn API */
74+
RtMidiInPtr rtmidi_in_create_default ()
75+
{
76+
return new RtMidiIn ();
77+
}
78+
79+
RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsigned int queueSizeLimit)
80+
{
81+
std::string name = clientName;
82+
return new RtMidiIn ((RtMidi::Api) api, name, queueSizeLimit);
83+
}
84+
85+
void rtmidi_in_free (RtMidiInPtr device)
86+
{
87+
delete (RtMidiIn*) device;
88+
}
89+
90+
enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device)
91+
{
92+
return (RtMidiApi) ((RtMidiIn*) device)->getCurrentApi ();
93+
}
94+
95+
class CallbackProxyUserData
96+
{
97+
public:
98+
CallbackProxyUserData (RtMidiCCallback cCallback, void *userData)
99+
: c_callback (cCallback), user_data (userData)
100+
{
101+
}
102+
RtMidiCCallback c_callback;
103+
void *user_data;
104+
};
105+
106+
void callback_proxy (double timeStamp, std::vector<unsigned char> *message, void *userData)
107+
{
108+
CallbackProxyUserData* data = reinterpret_cast<CallbackProxyUserData*> (userData);
109+
data->c_callback (timeStamp, message->data (), data->user_data);
110+
}
111+
112+
void rtmidi_in_set_callback (RtMidiInPtr device, RtMidiCCallback callback, void *userData)
113+
{
114+
void *data = (void *) new CallbackProxyUserData (callback, userData);
115+
((RtMidiIn*) device)->setCallback (callback_proxy, data);
116+
}
117+
118+
void rtmidi_in_cancel_callback (RtMidiInPtr device)
119+
{
120+
((RtMidiIn*) device)->cancelCallback ();
121+
}
122+
123+
void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool midiTime, bool midiSense)
124+
{
125+
((RtMidiIn*) device)->ignoreTypes (midiSysex, midiTime, midiSense);
126+
}
127+
128+
double rtmidi_in_get_message (RtMidiInPtr device, unsigned char **message)
129+
{
130+
try {
131+
// FIXME: use allocator to achieve efficient buffering
132+
std::vector<unsigned char> *v = new std::vector<unsigned char> ();
133+
double ret = ((RtMidiIn*) device)->getMessage (v);
134+
*message = (unsigned char *) malloc ((int) ret);
135+
memcpy (*message, v->data (), (int) ret);
136+
delete v;
137+
return ret;
138+
} catch (...) {
139+
return -1;
140+
}
141+
}
142+
143+
/* RtMidiOut API */
144+
RtMidiOutPtr rtmidi_out_create_default ()
145+
{
146+
return new RtMidiOut ();
147+
}
148+
149+
RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName)
150+
{
151+
std::string name = clientName;
152+
return new RtMidiOut ((RtMidi::Api) api, name);
153+
}
154+
155+
void rtmidi_out_free (RtMidiOutPtr device)
156+
{
157+
delete (RtMidiOut*) device;
158+
}
159+
160+
enum RtMidiApi rtmidi_out_get_current_api (RtMidiPtr device)
161+
{
162+
return (RtMidiApi) ((RtMidiOut*) device)->getCurrentApi ();
163+
}
164+
165+
int rtmidi_out_send_message (RtMidiOutPtr device, const unsigned char *message, int length)
166+
{
167+
try {
168+
// FIXME: use allocator to achieve efficient buffering
169+
std::vector<unsigned char> *v = new std::vector<unsigned char> (length);
170+
memcpy (v->data (), message, length);
171+
((RtMidiOut*) device)->sendMessage (v);
172+
delete v;
173+
return 0;
174+
} catch (...) {
175+
return -1;
176+
}
177+
}

rtmidi_c.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
#include <stdbool.h>
3+
4+
#ifndef RTMIDI_C_H
5+
#define RTMIDI_C_H
6+
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
typedef void* RtMidiPtr;
12+
typedef void* RtMidiInPtr;
13+
typedef void* RtMidiOutPtr;
14+
15+
enum RtMidiApi {
16+
RT_MIDI_API_UNSPECIFIED, /*!< Search for a working compiled API. */
17+
RT_MIDI_API_MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */
18+
RT_MIDI_API_LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
19+
RT_MIDI_API_UNIX_JACK, /*!< The Jack Low-Latency MIDI Server API. */
20+
RT_MIDI_API_WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */
21+
RT_MIDI_API_WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */
22+
RT_MIDI_API_RTMIDI_DUMMY /*!< A compilable but non-functional API. */
23+
};
24+
25+
enum RtMidiErrorType {
26+
RT_ERROR_WARNING, RT_ERROR_DEBUG_WARNING, RT_ERROR_UNSPECIFIED, RT_ERROR_NO_DEVICES_FOUND,
27+
RT_ERROR_INVALID_DEVICE, RT_ERROR_MEMORY_ERROR, RT_ERROR_INVALID_PARAMETER, RT_ERROR_INVALID_USE,
28+
RT_ERROR_DRIVER_ERROR, RT_ERROR_SYSTEM_ERROR, RT_ERROR_THREAD_ERROR
29+
};
30+
31+
typedef void(* RtMidiCCallback) (double timeStamp, const unsigned char* message, void *userData);
32+
33+
int rtmidi_sizeof_rtmidi_api ();
34+
35+
/* RtMidi API */
36+
int rtmidi_get_compiled_api (enum RtMidiApi **apis); // return length for NULL argument.
37+
void rtmidi_error (enum RtMidiErrorType type, const char* errorString);
38+
39+
void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *portName);
40+
void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName);
41+
void rtmidi_close_port (RtMidiPtr device);
42+
unsigned int rtmidi_get_port_count (RtMidiPtr device);
43+
const char* rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber);
44+
45+
/* RtMidiIn API */
46+
RtMidiInPtr rtmidi_in_create_default ();
47+
RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsigned int queueSizeLimit);
48+
void rtmidi_in_free (RtMidiInPtr device);
49+
enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device);
50+
void rtmidi_in_set_callback (RtMidiInPtr device, RtMidiCCallback callback, void *userData);
51+
void rtmidi_in_cancel_callback (RtMidiInPtr device);
52+
void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool midiTime, bool midiSense);
53+
double rtmidi_in_get_message (RtMidiInPtr device, unsigned char **message);
54+
55+
/* RtMidiOut API */
56+
RtMidiOutPtr rtmidi_out_create_default ();
57+
RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName);
58+
void rtmidi_out_free (RtMidiOutPtr device);
59+
enum RtMidiApi rtmidi_out_get_current_api (RtMidiPtr device);
60+
int rtmidi_out_send_message (RtMidiOutPtr device, const unsigned char *message, int length);
61+
62+
63+
#ifdef __cplusplus
64+
}
65+
#endif
66+
#endif

0 commit comments

Comments
 (0)