Browse Source

upgrade to 5.0.0

master
parent
commit
a192f6dc97
Signed by: alex
GPG Key ID: 022EAE42313D70F3
  1. 85
      CMakeLists.txt
  2. 35
      README.md
  3. 20
      configure.ac
  4. 2
      meson.build
  5. 4
      rtmidi.pc.in
  6. 703
      rtmidi/RtMidi.cpp
  7. 41
      rtmidi/RtMidi.h
  8. 72
      rtmidi/rtmidi_c.cpp
  9. 19
      rtmidi/rtmidi_c.h

85
CMakeLists.txt

@ -5,7 +5,12 @@ @@ -5,7 +5,12 @@
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
# Define a C++ project.
project(RtMidi LANGUAGES CXX)
project(RtMidi LANGUAGES CXX C)
# standards version
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Check for Jack (any OS)
find_library(JACK_LIB jack)
@ -76,8 +81,10 @@ string(REGEX REPLACE ${R} "\\1" PACKAGE_VERSION ${CONFIGAC}) @@ -76,8 +81,10 @@ string(REGEX REPLACE ${R} "\\1" PACKAGE_VERSION ${CONFIGAC})
# Init variables
set(rtmidi_SOURCES RtMidi.cpp RtMidi.h rtmidi_c.cpp rtmidi_c.h)
set(LINKLIBS)
set(PUBLICLINKLIBS)
set(INCDIRS)
set(PKGCONFIG_REQUIRES)
set(LIBS_REQUIRES)
set(API_DEFS)
set(API_LIST)
@ -106,7 +113,7 @@ if(RTMIDI_API_JACK) @@ -106,7 +113,7 @@ if(RTMIDI_API_JACK)
check_symbol_exists(jack_port_rename ${jack_INCLUDEDIR}/jack/jack.h JACK_HAS_PORT_RENAME)
set(CMAKE_REQUIRED_LIBRARIES ${tmp_CMAKE_REQUIRED_LIBRARIES})
if(JACK_HAS_PORT_RENAME)
list(APPEND API_DEFS "JACK_HAS_PORT_RENAME")
list(APPEND API_DEFS "-DJACK_HAS_PORT_RENAME")
endif()
endif()
@ -133,12 +140,14 @@ endif() @@ -133,12 +140,14 @@ endif()
# CoreMIDI
if(RTMIDI_API_CORE)
find_library(CORESERVICES_LIB CoreServices)
find_library(COREAUDIO_LIB CoreAudio)
find_library(COREMIDI_LIB CoreMIDI)
find_library(COREFOUNDATION_LIB CoreFoundation)
list(APPEND API_DEFS "-D__MACOSX_CORE__")
list(APPEND API_LIST "coremidi")
list(APPEND LINKLIBS "-framework CoreServices")
list(APPEND LINKLIBS "-framework CoreAudio")
list(APPEND LINKLIBS "-framework CoreMIDI")
list(APPEND LINKLIBS "-framework CoreFoundation")
list(APPEND LINKLIBS ${CORESERVICES_LIB} ${COREAUDIO_LIB} ${COREMIDI_LIB} ${COREFOUNDATION_LIB})
list(APPEND LIBS_REQUIRES "-framework CoreServices -framework CoreAudio -framework CoreMIDI -framework CoreFoundation")
list(APPEND LINKFLAGS "-Wl,-F/Library/Frameworks")
endif()
@ -147,11 +156,10 @@ if (NEED_PTHREAD) @@ -147,11 +156,10 @@ if (NEED_PTHREAD)
find_package(Threads REQUIRED
CMAKE_THREAD_PREFER_PTHREAD
THREADS_PREFER_PTHREAD_FLAG)
list(APPEND LINKLIBS Threads::Threads)
list(APPEND PUBLICLINKLIBS Threads::Threads)
endif()
# Create library targets.
cmake_policy(SET CMP0042 OLD)
set(LIB_TARGETS)
# Use RTMIDI_BUILD_SHARED_LIBS / RTMIDI_BUILD_STATIC_LIBS if they
@ -174,30 +182,33 @@ endif() @@ -174,30 +182,33 @@ endif()
list(APPEND LIB_TARGETS rtmidi)
# Add headers destination for install rule.
set_target_properties(rtmidi PROPERTIES PUBLIC_HEADER RtMidi.h
set_property(TARGET rtmidi PROPERTY PUBLIC_HEADER RtMidi.h rtmidi_c.h)
set_target_properties(rtmidi PROPERTIES
SOVERSION ${SO_VER}
VERSION ${FULL_VER})
# Set include paths, populate target interface.
target_include_directories(rtmidi PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
${INCDIRS})
target_include_directories(rtmidi PRIVATE ${INCDIRS}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
# Set compile-time definitions
target_compile_definitions(rtmidi PRIVATE ${API_DEFS})
target_compile_definitions(rtmidi PRIVATE RTMIDI_EXPORT)
target_link_libraries(rtmidi ${LINKLIBS})
target_link_libraries(rtmidi PUBLIC ${PUBLICLINKLIBS}
PRIVATE ${LINKLIBS})
# Set standard installation directories.
include(GNUInstallDirs)
# Add tests if requested.
include(CTest)
option(RTMIDI_BUILD_TESTING "Build test programs" ON)
if (NOT DEFINED RTMIDI_BUILD_TESTING OR RTMIDI_BUILD_TESTING STREQUAL "")
set(RTMIDI_BUILD_TESTING ${BUILD_TESTING})
endif()
if (RTMIDI_BUILD_TESTING)
include(CTest)
add_executable(cmidiin tests/cmidiin.cpp)
add_executable(midiclock tests/midiclock.cpp)
add_executable(midiout tests/midiout.cpp)
@ -205,8 +216,9 @@ if (RTMIDI_BUILD_TESTING) @@ -205,8 +216,9 @@ if (RTMIDI_BUILD_TESTING)
add_executable(qmidiin tests/qmidiin.cpp)
add_executable(sysextest tests/sysextest.cpp)
add_executable(apinames tests/apinames.cpp)
add_executable(testcapi tests/testcapi.c)
list(GET LIB_TARGETS 0 LIBRTMIDI)
set_target_properties(cmidiin midiclock midiout midiprobe qmidiin sysextest apinames
set_target_properties(cmidiin midiclock midiout midiprobe qmidiin sysextest apinames testcapi
PROPERTIES RUNTIME_OUTPUT_DIRECTORY tests
INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}
LINK_LIBRARIES ${LIBRTMIDI})
@ -222,7 +234,9 @@ message(STATUS "Compiling with support for: ${apilist}") @@ -222,7 +234,9 @@ message(STATUS "Compiling with support for: ${apilist}")
# PkgConfig file
string(REPLACE ";" " " req "${PKGCONFIG_REQUIRES}")
string(REPLACE ";" " " req_libs "${LIBS_REQUIRES}")
string(REPLACE ";" " " api "${API_DEFS}")
set(prefix ${CMAKE_INSTALL_PREFIX})
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rtmidi.pc.in" "rtmidi.pc" @ONLY)
# Add install rule.
@ -231,7 +245,7 @@ install(TARGETS ${LIB_TARGETS} @@ -231,7 +245,7 @@ install(TARGETS ${LIB_TARGETS}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rtmidi)
# Store the package in the user registry.
export(PACKAGE RtMidi)
@ -239,17 +253,6 @@ export(PACKAGE RtMidi) @@ -239,17 +253,6 @@ export(PACKAGE RtMidi)
# Set installation path for CMake files.
set(RTMIDI_CMAKE_DESTINATION share/rtmidi)
# Create CMake configuration export file.
if(NEED_PTHREAD)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/RtMidiConfig.cmake "find_package(Threads REQUIRED)\n")
endif()
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/RtMidiConfig.cmake "include(\${CMAKE_CURRENT_LIST_DIR}/RtMidiTargets.cmake)")
# Install CMake configuration export file.
install(FILES ${CMAKE_BINARY_DIR}/RtMidiConfig.cmake
DESTINATION ${RTMIDI_CMAKE_DESTINATION})
# Export library target (build-tree).
export(EXPORT RtMidiTargets
NAMESPACE RtMidi::)
@ -271,3 +274,29 @@ add_custom_target(${RTMIDI_TARGETNAME_UNINSTALL} @@ -271,3 +274,29 @@ add_custom_target(${RTMIDI_TARGETNAME_UNINSTALL}
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/rtmidi.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Set up CMake package
include(CMakePackageConfigHelpers)
# Write cmake package version file
write_basic_package_version_file(
RtMidi-config-version.cmake
VERSION ${FULL_VER}
COMPATIBILITY SameMajorVersion
)
# Write cmake package config file
configure_package_config_file (
cmake/RtMidi-config.cmake.in
RtMidi-config.cmake
INSTALL_DESTINATION "${RTMIDI_CMAKE_DESTINATION}"
)
# Install package files
install (
FILES
"${CMAKE_CURRENT_BINARY_DIR}/RtMidi-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/RtMidi-config-version.cmake"
DESTINATION
"${RTMIDI_CMAKE_DESTINATION}"
)

35
README.md

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
# RtMidi
[![Build Status](https://travis-ci.org/thestk/rtmidi.svg?branch=master)](https://travis-ci.org/thestk/rtmidi)
![Build Status](https://github.com/thestk/rtmidi/actions/workflows/ci.yml/badge.svg)
A set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI & JACK) and Windows (Multimedia).
By Gary P. Scavone, 2003-2019.
By Gary P. Scavone, 2003-2021.
This distribution of RtMidi contains the following:
@ -24,7 +24,7 @@ RtMidi is a set of C++ classes (`RtMidiIn`, `RtMidiOut`, and API specific classe @@ -24,7 +24,7 @@ RtMidi is a set of C++ classes (`RtMidiIn`, `RtMidiOut`, and API specific classe
- only one header and one source file for easy inclusion in programming projects
- MIDI device enumeration
MIDI input and output functionality are separated into two classes, `RtMidiIn` and `RtMidiOut`. Each class instance supports only a single MIDI connection. RtMidi does not provide timing functionality (i.e., output messages are sent immediately). Input messages are timestamped with delta times in seconds (via a `double` floating point type). MIDI data is passed to the user as raw bytes using an `std::vector&lt;unsigned char&gt;`.
MIDI input and output functionality are separated into two classes, `RtMidiIn` and `RtMidiOut`. Each class instance supports only a single MIDI connection. RtMidi does not provide timing functionality (i.e., output messages are sent immediately). Input messages are timestamped with delta times in seconds (via a `double` floating point type). MIDI data is passed to the user as raw bytes using an `std::vector<unsigned char>`.
## Windows
@ -36,31 +36,4 @@ For complete documentation on RtMidi, see the `doc` directory of the distributio @@ -36,31 +36,4 @@ For complete documentation on RtMidi, see the `doc` directory of the distributio
## Legal and ethical
The RtMidi license is similar to the MIT License, with the added *feature* that modifications be sent to the developer.
RtMidi: realtime MIDI i/o C++ classes
Copyright (c) 2003-2019 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
Any person wishing to distribute modifications to the Software is
asked to send the modifications to the original developer so that
they can be incorporated into the canonical version. This is,
however, not a binding provision of this license.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The RtMidi license is similar to the MIT License, with the added *feature* that modifications be sent to the developer. Please see [LICENSE](LICENSE).

20
configure.ac

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(RtMidi, 4.0.0, gary@music.mcgill.ca, rtmidi)
AC_INIT(RtMidi, 5.0.0, gary.scavone@mcgill.ca, rtmidi)
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_SRCDIR(RtMidi.cpp)
AC_CONFIG_FILES([rtmidi-config rtmidi.pc Makefile tests/Makefile doc/Makefile doc/doxygen/Doxyfile])
@ -18,7 +18,7 @@ AM_INIT_AUTOMAKE([1.14 -Wall -Werror foreign subdir-objects]) @@ -18,7 +18,7 @@ AM_INIT_AUTOMAKE([1.14 -Wall -Werror foreign subdir-objects])
#
# If any interfaces have been removed since the last public release, then set
# age to 0.
m4_define([lt_current], 5)
m4_define([lt_current], 6)
m4_define([lt_revision], 0)
m4_define([lt_age], 0)
@ -30,9 +30,11 @@ AC_SUBST(SO_VERSION) @@ -30,9 +30,11 @@ AC_SUBST(SO_VERSION)
AC_SUBST(LIBS)
AC_SUBST(api)
AC_SUBST(req)
AC_SUBST(req_libs)
api=""
req=""
req_libs=""
# Fill GXX with something before test.
GXX="no"
@ -52,6 +54,10 @@ AS_IF( @@ -52,6 +54,10 @@ AS_IF(
m4_ifdef([AM_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# standards version
m4_include([m4/ax_cxx_compile_stdcxx.m4])
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
# configure flags
AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [enable various debugging output])])
AC_ARG_WITH(jack, [AS_HELP_STRING([--with-jack], [choose JACK server support])])
@ -59,6 +65,7 @@ AC_ARG_WITH(alsa, [AS_HELP_STRING([--with-alsa], [choose native ALSA sequencer A @@ -59,6 +65,7 @@ AC_ARG_WITH(alsa, [AS_HELP_STRING([--with-alsa], [choose native ALSA sequencer A
AC_ARG_WITH(core, [AS_HELP_STRING([--with-core], [ choose CoreMIDI API support (mac only)])])
AC_ARG_WITH(winmm, [AS_HELP_STRING([--with-winmm], [ choose Windows MultiMedia (MM) API support (win32 only)])])
AC_ARG_WITH(winks, [AS_HELP_STRING([--with-winks], [ choose kernel streaming support (win32 only)])])
AC_ARG_WITH(webmidi, [AS_HELP_STRING([--with-webmidi], [ choose Web MIDI support])])
# Checks for programs.
@ -132,6 +139,7 @@ AS_IF([test "x$with_alsa" = "xyes"], [systems="$systems alsa"]) @@ -132,6 +139,7 @@ AS_IF([test "x$with_alsa" = "xyes"], [systems="$systems alsa"])
AS_IF([test "x$with_core" = "xyes"], [systems="$systems core"])
AS_IF([test "x$with_winmm" = "xyes"], [systems="$systems winmm"])
AS_IF([test "x$with_winks" = "xyes"], [systems="$systems winks"])
AS_IF([test "x$with_webmidi" = "xyes"], [systems="$systems webmidi"])
AS_IF([test "x$with_dummy" = "xyes"], [systems="$systems dummy"])
required=" $systems "
@ -153,6 +161,7 @@ AS_IF([test "x$with_alsa" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep @@ -153,6 +161,7 @@ AS_IF([test "x$with_alsa" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep
AS_IF([test "x$with_winmm" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep -v winmm`])
AS_IF([test "x$with_winks" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep -v winks`])
AS_IF([test "x$with_core" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep -v core`])
AS_IF([test "x$with_webmidi" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep -v webmidi`])
AS_IF([test "x$with_dummy" = "xno"], [systems=`echo $systems|tr ' ' \\\\n|grep -v dummy`])
systems=" `echo $systems|tr \\\\n ' '` "
@ -187,6 +196,7 @@ AS_CASE(["$systems"], [*" alsa "*], [ @@ -187,6 +196,7 @@ AS_CASE(["$systems"], [*" alsa "*], [
AS_CASE(["$systems"], [*" core "*], [
AC_CHECK_HEADER(CoreMIDI/CoreMIDI.h,
[api="$api -D__MACOSX_CORE__"
req_libs="$req_libs -framework CoreMIDI -framework CoreAudio -framework CoreFoundation"
need_pthread=yes
found="$found CoreMIDI",
LIBS="$LIBS -framework CoreMIDI -framework CoreFoundation -framework CoreAudio"],
@ -214,6 +224,12 @@ AS_CASE(["$systems"], [*" winks "*], [ @@ -214,6 +224,12 @@ AS_CASE(["$systems"], [*" winks "*], [
LIBS="-lsetupapi -lksuser ${LIBS}"])
])
AS_CASE(["$systems"], [*" webmidi "*], [
AC_CHECK_HEADERS(emscripten.h,
[api="$api -D__WEB_MIDI_API__"
found="$found Web MIDI"])
])
AS_IF([test -n "$need_ole32"], [LIBS="-lole32 $LIBS"])
AS_IF([test -n "$need_pthread"],[

2
meson.build

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
project (
'zrythm-midi', ['c', 'cpp'],
version: '4.0.0',
version: '5.0.0',
license: 'MIT',
default_options: [
'warning_level=1',

4
rtmidi.pc.in

@ -6,7 +6,7 @@ includedir=${prefix}/include/rtmidi @@ -6,7 +6,7 @@ includedir=${prefix}/include/rtmidi
Name: librtmidi
Description: RtMidi - a set of C++ classes that provide a common API for realtime MIDI input/output
Version: @PACKAGE_VERSION@
Requires: @req@
Requires.private: @req@
Libs: -L${libdir} -lrtmidi
Libs.private: -lpthread
Libs.private: -lpthread @req_libs@
Cflags: -pthread -I${includedir} @api@

703
rtmidi/RtMidi.cpp

File diff suppressed because it is too large Load Diff

41
rtmidi/RtMidi.h

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
RtMidi WWW site: http://www.music.mcgill.ca/~gary/rtmidi/
RtMidi: realtime MIDI i/o C++ classes
Copyright (c) 2003-2019 Gary P. Scavone
Copyright (c) 2003-2021 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@ -58,13 +58,14 @@ @@ -58,13 +58,14 @@
#endif
#endif
#define RTMIDI_VERSION "4.0.0"
#define RTMIDI_VERSION "5.0.0"
#include <exception>
#include <iostream>
#include <string>
#include <vector>
/************************************************************************/
/*! \class RtMidiError
\brief Exception handling class for RtMidi.
@ -132,6 +133,8 @@ class MidiApi; @@ -132,6 +133,8 @@ class MidiApi;
class RTMIDI_DLL_PUBLIC RtMidi
{
public:
RtMidi(RtMidi&& other) noexcept;
//! MIDI API specifier arguments.
enum Api {
UNSPECIFIED, /*!< Search for a working compiled API. */
@ -140,6 +143,7 @@ class RTMIDI_DLL_PUBLIC RtMidi @@ -140,6 +143,7 @@ class RTMIDI_DLL_PUBLIC RtMidi
UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */
WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */
RTMIDI_DUMMY, /*!< A compilable but non-functional API. */
WEB_MIDI_API, /*!< W3C Web MIDI API. */
NUM_APIS /*!< Number of values in this enum. */
};
@ -213,6 +217,10 @@ class RTMIDI_DLL_PUBLIC RtMidi @@ -213,6 +217,10 @@ class RTMIDI_DLL_PUBLIC RtMidi
RtMidi();
virtual ~RtMidi();
MidiApi *rtapi_;
/* Make the class non-copyable */
RtMidi(RtMidi& other) = delete;
RtMidi& operator=(RtMidi& other) = delete;
};
/**********************************************************************/
@ -228,8 +236,6 @@ class RTMIDI_DLL_PUBLIC RtMidi @@ -228,8 +236,6 @@ class RTMIDI_DLL_PUBLIC RtMidi
time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also
possible to open a virtual input port to which other MIDI software
clients can connect.
by Gary P. Scavone, 2003-2017.
*/
/**********************************************************************/
@ -250,7 +256,6 @@ class RTMIDI_DLL_PUBLIC RtMidi @@ -250,7 +256,6 @@ class RTMIDI_DLL_PUBLIC RtMidi
class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
{
public:
//! User callback function type definition.
typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData );
@ -276,6 +281,8 @@ class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi @@ -276,6 +281,8 @@ class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
const std::string& clientName = "RtMidi Input Client",
unsigned int queueSizeLimit = 100 );
RtMidiIn(RtMidiIn&& other) noexcept : RtMidi(std::move(other)) { }
//! If a MIDI connection is still open, it will be closed by the destructor.
~RtMidiIn ( void ) throw();
@ -373,6 +380,19 @@ class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi @@ -373,6 +380,19 @@ class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
*/
virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
//! Set maximum expected incoming message size.
/*!
For APIs that require manual buffer management, it can be useful to set the buffer
size and buffer count when expecting to receive large SysEx messages. Note that
currently this function has no effect when called after openPort(). The default
buffer size is 1024 with a count of 4 buffers, which should be sufficient for most
cases; as mentioned, this does not affect all API backends, since most either support
dynamically scalable buffers or take care of buffer handling themselves. It is
principally intended for users of the Windows MM backend who must support receiving
especially large messages.
*/
virtual void setBufferSize( unsigned int size, unsigned int count );
protected:
void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit );
};
@ -388,8 +408,6 @@ class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi @@ -388,8 +408,6 @@ class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
connect to more than one MIDI device at the same time. With the
OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a
virtual port to which other MIDI software clients can connect.
by Gary P. Scavone, 2003-2017.
*/
/**********************************************************************/
@ -407,6 +425,8 @@ class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi @@ -407,6 +425,8 @@ class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi
RtMidiOut( RtMidi::Api api=UNSPECIFIED,
const std::string& clientName = "RtMidi Output Client" );
RtMidiOut(RtMidiOut&& other) noexcept : RtMidi(std::move(other)) { }
//! The destructor closes any open MIDI connections.
~RtMidiOut( void ) throw();
@ -527,6 +547,7 @@ protected: @@ -527,6 +547,7 @@ protected:
RtMidiErrorCallback errorCallback_;
bool firstErrorOccurred_;
void *errorCallbackUserData_;
};
class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
@ -539,6 +560,7 @@ class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi @@ -539,6 +560,7 @@ class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
void cancelCallback( void );
virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
double getMessage( std::vector<unsigned char> *message );
virtual void setBufferSize( unsigned int size, unsigned int count );
// A MIDI structure used internally by the class to store incoming
// messages. Each message represents one and only one MIDI message.
@ -580,11 +602,13 @@ class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi @@ -580,11 +602,13 @@ class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
RtMidiIn::RtMidiCallback userCallback;
void *userData;
bool continueSysex;
unsigned int bufferSize;
unsigned int bufferCount;
// Default constructor.
RtMidiInData()
: ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false),
userCallback(0), userData(0), continueSysex(false) {}
userCallback(0), userData(0), continueSysex(false), bufferSize(1024), bufferCount(4) {}
};
protected:
@ -618,6 +642,7 @@ inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return r @@ -618,6 +642,7 @@ inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return r
inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { static_cast<MidiInApi *>(rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return static_cast<MidiInApi *>(rtapi_)->getMessage( message ); }
inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
inline void RtMidiIn :: setBufferSize( unsigned int size, unsigned int count ) { static_cast<MidiInApi *>(rtapi_)->setBufferSize(size, count); }
inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }

72
rtmidi/rtmidi_c.cpp

@ -34,12 +34,12 @@ class StaticAssertions { StaticAssertions() { @@ -34,12 +34,12 @@ class StaticAssertions { StaticAssertions() {
class CallbackProxyUserData
{
public:
CallbackProxyUserData (RtMidiCCallback cCallback, void *userData)
: c_callback (cCallback), user_data (userData)
{
}
RtMidiCCallback c_callback;
void *user_data;
CallbackProxyUserData (RtMidiCCallback cCallback, void *userData)
: c_callback (cCallback), user_data (userData)
{
}
RtMidiCCallback c_callback;
void *user_data;
};
extern "C" const enum RtMidiApi rtmidi_compiled_apis[]; // casting from RtMidi::Api[]
@ -80,8 +80,8 @@ enum RtMidiApi rtmidi_compiled_api_by_name(const char *name) { @@ -80,8 +80,8 @@ enum RtMidiApi rtmidi_compiled_api_by_name(const char *name) {
void rtmidi_error (MidiApi *api, enum RtMidiErrorType type, const char* errorString)
{
std::string msg = errorString;
api->error ((RtMidiError::Type) type, msg);
std::string msg = errorString;
api->error ((RtMidiError::Type) type, msg);
}
void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *portName)
@ -89,7 +89,7 @@ void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *po @@ -89,7 +89,7 @@ void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *po
std::string name = portName;
try {
((RtMidi*) device->ptr)->openPort (portNumber, name);
} catch (const RtMidiError & err) {
device->ok = false;
device->msg = err.what ();
@ -101,7 +101,7 @@ void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName) @@ -101,7 +101,7 @@ void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName)
std::string name = portName;
try {
((RtMidi*) device->ptr)->openVirtualPort (name);
} catch (const RtMidiError & err) {
device->ok = false;
device->msg = err.what ();
@ -111,7 +111,7 @@ void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName) @@ -111,7 +111,7 @@ void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName)
void rtmidi_close_port (RtMidiPtr device)
{
try {
try {
((RtMidi*) device->ptr)->closePort ();
} catch (const RtMidiError & err) {
@ -132,32 +132,42 @@ unsigned int rtmidi_get_port_count (RtMidiPtr device) @@ -132,32 +132,42 @@ unsigned int rtmidi_get_port_count (RtMidiPtr device)
}
}
const char* rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber)
int rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber, char * bufOut, int * bufLen)
{
if (bufOut == nullptr && bufLen == nullptr) {
return -1;
}
std::string name;
try {
std::string name = ((RtMidi*) device->ptr)->getPortName (portNumber);
return strdup (name.c_str ());
name = ((RtMidi*) device->ptr)->getPortName (portNumber);
} catch (const RtMidiError & err) {
device->ok = false;
device->msg = err.what ();
return "";
return -1;
}
if (bufOut == nullptr) {
*bufLen = static_cast<int>(name.size()) + 1;
return 0;
}
return snprintf(bufOut, static_cast<size_t>(*bufLen), "%s", name.c_str());
}
/* RtMidiIn API */
RtMidiInPtr rtmidi_in_create_default ()
{
RtMidiWrapper* wrp = new RtMidiWrapper;
try {
RtMidiIn* rIn = new RtMidiIn ();
wrp->ptr = (void*) rIn;
wrp->data = 0;
wrp->ok = true;
wrp->msg = "";
} catch (const RtMidiError & err) {
wrp->ptr = 0;
wrp->data = 0;
@ -172,10 +182,10 @@ RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsign @@ -172,10 +182,10 @@ RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsign
{
std::string name = clientName;
RtMidiWrapper* wrp = new RtMidiWrapper;
try {
RtMidiIn* rIn = new RtMidiIn ((RtMidi::Api) api, name, queueSizeLimit);
wrp->ptr = (void*) rIn;
wrp->data = 0;
wrp->ok = true;
@ -203,7 +213,7 @@ enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device) @@ -203,7 +213,7 @@ enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device)
{
try {
return (RtMidiApi) ((RtMidiIn*) device->ptr)->getCurrentApi ();
} catch (const RtMidiError & err) {
device->ok = false;
device->msg = err.what ();
@ -215,8 +225,8 @@ enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device) @@ -215,8 +225,8 @@ enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device)
static
void callback_proxy (double timeStamp, std::vector<unsigned char> *message, void *userData)
{
CallbackProxyUserData* data = reinterpret_cast<CallbackProxyUserData*> (userData);
data->c_callback (timeStamp, message->data (), message->size (), data->user_data);
CallbackProxyUserData* data = reinterpret_cast<CallbackProxyUserData*> (userData);
data->c_callback (timeStamp, message->data (), message->size (), data->user_data);
}
void rtmidi_in_set_callback (RtMidiInPtr device, RtMidiCCallback callback, void *userData)
@ -246,10 +256,10 @@ void rtmidi_in_cancel_callback (RtMidiInPtr device) @@ -246,10 +256,10 @@ void rtmidi_in_cancel_callback (RtMidiInPtr device)
void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool midiTime, bool midiSense)
{
((RtMidiIn*) device->ptr)->ignoreTypes (midiSysex, midiTime, midiSense);
((RtMidiIn*) device->ptr)->ignoreTypes (midiSysex, midiTime, midiSense);
}
double rtmidi_in_get_message (RtMidiInPtr device,
double rtmidi_in_get_message (RtMidiInPtr device,
unsigned char *message,
size_t *size)
{
@ -264,7 +274,7 @@ double rtmidi_in_get_message (RtMidiInPtr device, @@ -264,7 +274,7 @@ double rtmidi_in_get_message (RtMidiInPtr device,
*size = v.size();
return ret;
}
}
catch (const RtMidiError & err) {
device->ok = false;
device->msg = err.what ();
@ -284,12 +294,12 @@ RtMidiOutPtr rtmidi_out_create_default () @@ -284,12 +294,12 @@ RtMidiOutPtr rtmidi_out_create_default ()
try {
RtMidiOut* rOut = new RtMidiOut ();
wrp->ptr = (void*) rOut;
wrp->data = 0;
wrp->ok = true;
wrp->msg = "";
} catch (const RtMidiError & err) {
wrp->ptr = 0;
wrp->data = 0;
@ -307,12 +317,12 @@ RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName) @@ -307,12 +317,12 @@ RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName)
try {
RtMidiOut* rOut = new RtMidiOut ((RtMidi::Api) api, name);
wrp->ptr = (void*) rOut;
wrp->data = 0;
wrp->ok = true;
wrp->msg = "";
} catch (const RtMidiError & err) {
wrp->ptr = 0;
wrp->data = 0;

19
rtmidi/rtmidi_c.h

@ -41,7 +41,7 @@ struct RtMidiWrapper { @@ -41,7 +41,7 @@ struct RtMidiWrapper {
void* ptr;
void* data;
//! True when the last function call was OK.
//! True when the last function call was OK.
bool ok;
//! If an error occured (ok != true), set to an error message.
@ -136,8 +136,8 @@ RTMIDIAPI void rtmidi_error (enum RtMidiErrorType type, const char* errorString) @@ -136,8 +136,8 @@ RTMIDIAPI void rtmidi_error (enum RtMidiErrorType type, const char* errorString)
*/
RTMIDIAPI void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *portName);
/*! \brief Creates a virtual MIDI port to which other software applications can
* connect.
/*! \brief Creates a virtual MIDI port to which other software applications can
* connect.
*
* \param portName Name for the application port.
*
@ -155,10 +155,14 @@ RTMIDIAPI void rtmidi_close_port (RtMidiPtr device); @@ -155,10 +155,14 @@ RTMIDIAPI void rtmidi_close_port (RtMidiPtr device);
*/
RTMIDIAPI unsigned int rtmidi_get_port_count (RtMidiPtr device);
/*! \brief Return a string identifier for the specified MIDI input port number.
/*! \brief Access a string identifier for the specified MIDI input port number.
*
* To prevent memory leaks a char buffer must be passed to this function.
* NULL can be passed as bufOut parameter, and that will write the required buffer length in the bufLen.
*
* See RtMidi::getPortName().
*/
RTMIDIAPI const char* rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber);
RTMIDIAPI int rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber, char * bufOut, int * bufLen);
/* RtMidiIn API */
@ -203,8 +207,9 @@ RTMIDIAPI void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool @@ -203,8 +207,9 @@ RTMIDIAPI void rtmidi_in_ignore_types (RtMidiInPtr device, bool midiSysex, bool
* \param message Must point to a char* that is already allocated.
* SYSEX messages maximum size being 1024, a statically
* allocated array could
* be sufficient.
* \param size Is used to return the size of the message obtained.
* be sufficient.
* \param size Is used to return the size of the message obtained.
* Must be set to the size of \ref message when calling.
*
* See RtMidiIn::getMessage().
*/

Loading…
Cancel
Save