Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add C API.
- Loading branch information
1 parent
28321c0
commit a5c375c
Showing
4 changed files
with
254 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |