summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtsushi Eno <atsushieno@gmail.com>2015-08-29 20:44:00 +0800
committerAtsushi Eno <atsushieno@gmail.com>2015-08-29 22:08:46 +0800
commita5c375c7280e2134391a7d840f4fbda0a7f684bb (patch)
tree096763ba565f26cd3ef4c6d13299f925ddc77808
parent28321c051ed849b0fbd1f7b1aaee19b8ca807390 (diff)
Add C API.
-rw-r--r--Makefile.am4
-rwxr-xr-xmsw/rtmidilib.vcproj8
-rw-r--r--rtmidi_c.cpp177
-rw-r--r--rtmidi_c.h66
4 files changed, 254 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 4851619..706daf0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,4 +2,6 @@ lib_LTLIBRARIES = %D%/librtmidi.la
%C%_librtmidi_la_LDFLAGS = -no-undefined
%C%_librtmidi_la_SOURCES = \
%D%/RtMidi.cpp \
- %D%/RtMidi.h
+ %D%/RtMidi.h \
+ %D%/rtmidi_c.cpp \
+ %D%/rtmidi_c.h
diff --git a/msw/rtmidilib.vcproj b/msw/rtmidilib.vcproj
index af1f75c..20a458f 100755
--- a/msw/rtmidilib.vcproj
+++ b/msw/rtmidilib.vcproj
@@ -151,6 +151,10 @@
RelativePath="..\RtMidi.cpp"
>
</File>
+ <File
+ RelativePath="..\rtmidi_c.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Header Files"
@@ -165,6 +169,10 @@
RelativePath="..\RtMidi.h"
>
</File>
+ <File
+ RelativePath="..\rtmidi_c.h"
+ >
+ </File>
</Filter>
<Filter
Name="Resource Files"
diff --git a/rtmidi_c.cpp b/rtmidi_c.cpp
new file mode 100644
index 0000000..8c2e676
--- /dev/null
+++ b/rtmidi_c.cpp
@@ -0,0 +1,177 @@
+#include <string.h>
+#include <stdlib.h>
+#include "rtmidi_c.h"
+#include "RtMidi.h"
+
+/* misc */
+int rtmidi_sizeof_rtmidi_api ()
+{
+ return sizeof (RtMidiApi);
+}
+
+/* RtMidi API */
+int rtmidi_get_compiled_api (enum RtMidiApi **apis) // return length for NULL argument.
+{
+ if (!apis || !(*apis)) {
+ std::vector<RtMidi::Api> *v = new std::vector<RtMidi::Api> ();
+ try {
+ RtMidi::getCompiledApi (*v);
+ int size = v->size ();
+ delete v;
+ return size;
+ } catch (...) {
+ return -1;
+ }
+ } else {
+ try {
+ std::vector<RtMidi::Api> *v = new std::vector<RtMidi::Api> ();
+ RtMidi::getCompiledApi (*v);
+ for (unsigned int i = 0; i < v->size (); i++)
+ (*apis) [i] = (RtMidiApi) v->at (i);
+ delete v;
+ return 0;
+ } catch (...) {
+ return -1;
+ }
+ }
+}
+
+void rtmidi_error (MidiApi *api, enum RtMidiErrorType type, const char* errorString)
+{
+ std::string msg = errorString;
+ api->error ((RtMidiError::Type) type, msg);
+}
+
+void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *portName)
+{
+ std::string name = portName;
+ ((RtMidi*) device)->openPort (portNumber, name);
+}
+
+void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName)
+{
+ std::string name = portName;
+ ((RtMidi*) device)->openVirtualPort (name);
+}
+
+void rtmidi_close_port (RtMidiPtr device)
+{
+ ((RtMidi*) device)->closePort ();
+}
+
+unsigned int rtmidi_get_port_count (RtMidiPtr device)
+{
+ return ((RtMidi*) device)->getPortCount ();
+}
+
+const char* rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber)
+{
+ std::string name = ((RtMidi*) device)->getPortName (portNumber);
+ return name.c_str ();
+}
+
+/* RtMidiIn API */
+RtMidiInPtr rtmidi_in_create_default ()
+{
+ return new RtMidiIn ();
+}
+
+RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsigned int queueSizeLimit)
+{
+ std::string name = clientName;
+ return new RtMidiIn ((RtMidi::Api) api, name, queueSizeLimit);
+}
+
+void rtmidi_in_free (RtMidiInPtr device)
+{
+ delete (RtMidiIn*) device;
+}
+
+enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device)
+{
+ return (RtMidiApi) ((RtMidiIn*) device)->getCurrentApi ();
+}
+
+class CallbackProxyUserData
+{
+ public:
+ CallbackProxyUserData (RtMidiCCallback cCallback, void *userData)
+ : c_callback (cCallback), user_data (userData)
+ {
+ }
+ RtMidiCCallback c_callback;
+ void *user_data;
+};
+
+void callback_proxy (double timeStamp, std::vector<unsigned char> *message, void *userData)
+{
+ CallbackProxyUserData* data = reinterpret_cast<CallbackProxyUserData*> (userData);
+ data->c_callback (timeStamp, message->data (), data->user_data);
+}
+
+void rtmidi_in_set_callback (RtMidiInPtr device, RtMidiCCallback callback, void *userData)
+{
+ void *data = (void *) new CallbackProxyUserData (callback, userData);
+ ((RtMidiIn*) device)->setCallback (callback_proxy, data);
+}
+
+void rtmidi_in_cancel_callback (RtMidiInPtr device)
+{
+ ((RtMidiIn*) device)->cancelCallback ();
+}
+
+void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool midiTime, bool midiSense)
+{
+ ((RtMidiIn*) device)->ignoreTypes (midiSysex, midiTime, midiSense);
+}
+
+double rtmidi_in_get_message (RtMidiInPtr device, unsigned char **message)
+{
+ try {
+ // FIXME: use allocator to achieve efficient buffering
+ std::vector<unsigned char> *v = new std::vector<unsigned char> ();
+ double ret = ((RtMidiIn*) device)->getMessage (v);
+ *message = (unsigned char *) malloc ((int) ret);
+ memcpy (*message, v->data (), (int) ret);
+ delete v;
+ return ret;
+ } catch (...) {
+ return -1;
+ }
+}
+
+/* RtMidiOut API */
+RtMidiOutPtr rtmidi_out_create_default ()
+{
+ return new RtMidiOut ();
+}
+
+RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName)
+{
+ std::string name = clientName;
+ return new RtMidiOut ((RtMidi::Api) api, name);
+}
+
+void rtmidi_out_free (RtMidiOutPtr device)
+{
+ delete (RtMidiOut*) device;
+}
+
+enum RtMidiApi rtmidi_out_get_current_api (RtMidiPtr device)
+{
+ return (RtMidiApi) ((RtMidiOut*) device)->getCurrentApi ();
+}
+
+int rtmidi_out_send_message (RtMidiOutPtr device, const unsigned char *message, int length)
+{
+ try {
+ // FIXME: use allocator to achieve efficient buffering
+ std::vector<unsigned char> *v = new std::vector<unsigned char> (length);
+ memcpy (v->data (), message, length);
+ ((RtMidiOut*) device)->sendMessage (v);
+ delete v;
+ return 0;
+ } catch (...) {
+ return -1;
+ }
+}
diff --git a/rtmidi_c.h b/rtmidi_c.h
new file mode 100644
index 0000000..6630c44
--- /dev/null
+++ b/rtmidi_c.h
@@ -0,0 +1,66 @@
+
+#include <stdbool.h>
+
+#ifndef RTMIDI_C_H
+#define RTMIDI_C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* RtMidiPtr;
+typedef void* RtMidiInPtr;
+typedef void* RtMidiOutPtr;
+
+ enum RtMidiApi {
+ RT_MIDI_API_UNSPECIFIED, /*!< Search for a working compiled API. */
+ RT_MIDI_API_MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */
+ RT_MIDI_API_LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
+ RT_MIDI_API_UNIX_JACK, /*!< The Jack Low-Latency MIDI Server API. */
+ RT_MIDI_API_WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */
+ RT_MIDI_API_WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */
+ RT_MIDI_API_RTMIDI_DUMMY /*!< A compilable but non-functional API. */
+ };
+
+enum RtMidiErrorType {
+ RT_ERROR_WARNING, RT_ERROR_DEBUG_WARNING, RT_ERROR_UNSPECIFIED, RT_ERROR_NO_DEVICES_FOUND,
+ RT_ERROR_INVALID_DEVICE, RT_ERROR_MEMORY_ERROR, RT_ERROR_INVALID_PARAMETER, RT_ERROR_INVALID_USE,
+ RT_ERROR_DRIVER_ERROR, RT_ERROR_SYSTEM_ERROR, RT_ERROR_THREAD_ERROR
+};
+
+typedef void(* RtMidiCCallback) (double timeStamp, const unsigned char* message, void *userData);
+
+int rtmidi_sizeof_rtmidi_api ();
+
+/* RtMidi API */
+int rtmidi_get_compiled_api (enum RtMidiApi **apis); // return length for NULL argument.
+void rtmidi_error (enum RtMidiErrorType type, const char* errorString);
+
+void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *portName);
+void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName);
+void rtmidi_close_port (RtMidiPtr device);
+unsigned int rtmidi_get_port_count (RtMidiPtr device);
+const char* rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber);
+
+/* RtMidiIn API */
+RtMidiInPtr rtmidi_in_create_default ();
+RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsigned int queueSizeLimit);
+void rtmidi_in_free (RtMidiInPtr device);
+enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device);
+void rtmidi_in_set_callback (RtMidiInPtr device, RtMidiCCallback callback, void *userData);
+void rtmidi_in_cancel_callback (RtMidiInPtr device);
+void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool midiTime, bool midiSense);
+double rtmidi_in_get_message (RtMidiInPtr device, unsigned char **message);
+
+/* RtMidiOut API */
+RtMidiOutPtr rtmidi_out_create_default ();
+RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName);
+void rtmidi_out_free (RtMidiOutPtr device);
+enum RtMidiApi rtmidi_out_get_current_api (RtMidiPtr device);
+int rtmidi_out_send_message (RtMidiOutPtr device, const unsigned char *message, int length);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif