diff --git a/CMakeLists.txt b/CMakeLists.txt index 75d549f9..75c4a0f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,10 @@ if (HAVE_GETTIMEOFDAY) add_definitions(-DHAVE_GETTIMEOFDAY) endif () +# Module options +option(RTAUDIO_BUILD_MODULES "Build C++ modules for RtAudio" OFF) +option(RTAUDIO_USE_NAMESPACE "Force usage of namespace rt::audio for modules" ON) + # Add -Wall if possible if (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") @@ -279,6 +283,15 @@ target_compile_definitions(rtaudio PRIVATE ${API_DEFS}) target_compile_definitions(rtaudio PRIVATE RTAUDIO_EXPORT) target_link_libraries(rtaudio ${LINKLIBS}) +if(RTAUDIO_BUILD_MODULES) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) + message(STATUS "Building rtaudio C++ module") + add_subdirectory(modules) + else() + message(WARNING "Skipping rtaudio C++ module (requires CMake 3.28+, found ${CMAKE_VERSION})") + endif() +endif() + # Subdirs if (NOT DEFINED RTAUDIO_BUILD_TESTING OR RTAUDIO_BUILD_TESTING STREQUAL "") diff --git a/README.md b/README.md index 171ee8c2..28e41da1 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ RtAudio is a set of C++ classes that provides a common API (Application Programm RtAudio incorporates the concept of audio streams, which represent audio output (playback) and/or input (recording). Available audio devices and their capabilities can be enumerated and then specified when opening a stream. Where applicable, multiple API support can be compiled and a particular API specified when creating an RtAudio instance. See the \ref apinotes section for information specific to each of the supported audio APIs. +RtAudio is also offered as a module, which is enabled with `RTAUDIO_BUILD_MODULES`, and is accessed with `import rt.audio;`. Namespaces are inlined, so classes can be accessed through namespace `rt::audio` or through the global namespace (for example, `rt::audio::RtApi` and `::RtApi` are both valid). + ## Building Several build systems are available. These are: diff --git a/RtAudio.h b/RtAudio.h index ec71d9d0..a11c6232 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -85,6 +85,9 @@ #include #include +inline namespace rt { +inline namespace audio { + /*! \typedef typedef unsigned long RtAudioFormat; \brief RtAudio data format type. @@ -648,6 +651,9 @@ class RTAUDIO_DLL_PUBLIC RtAudio std::shared_ptr rtapi_; }; +} +} + // Operating system dependent thread functionality. #if defined(_MSC_VER) @@ -658,16 +664,24 @@ class RTAUDIO_DLL_PUBLIC RtAudio #include #include +inline namespace rt { +inline namespace audio { typedef uintptr_t ThreadHandle; typedef CRITICAL_SECTION StreamMutex; +} +} #else // Using pthread library for various flavors of unix. #include +inline namespace rt { +inline namespace audio { typedef pthread_t ThreadHandle; typedef pthread_mutex_t StreamMutex; +} +} #endif @@ -680,6 +694,9 @@ class RTAUDIO_DLL_PUBLIC RtAudio #endif +inline namespace rt { +inline namespace audio { + // This global structure type is used to pass callback information // between the private RtAudio stream structure and global callback // handling functions. @@ -738,12 +755,18 @@ class S24 { }; #pragma pack(pop) +} +} + #if defined( HAVE_GETTIMEOFDAY ) #include #endif #include +inline namespace rt { +inline namespace audio { + class RTAUDIO_DLL_PUBLIC RtApi { public: @@ -931,6 +954,9 @@ inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value #endif +} +} + // Indentation settings for Vim and Emacs // // Local Variables: diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 00000000..bc6b71f1 --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.28) + +add_library(rtaudio_modules) + +set(RTAUDIO_MODULES + RtAudio.cppm +) + + +if(NOT COMMAND configure_cpp_module_target) + function(configure_cpp_module_target target) + target_sources(${target} PUBLIC FILE_SET CXX_MODULES FILES ${RTAUDIO_MODULES}) + endfunction() +endif() + +if(RTAUDIO_USE_NAMESPACE) + target_compile_definitions(rtaudio_modules PRIVATE RTAUDIO_USE_NAMESPACE) +endif() + +configure_cpp_module_target(rtaudio_modules) + +target_link_libraries(rtaudio_modules + PUBLIC + rtaudio +) + +target_include_directories(rtaudio_modules + PRIVATE + ${PROJECT_SOURCE_DIR} +) + +target_compile_features(rtaudio_modules PUBLIC cxx_std_20) diff --git a/modules/RtAudio.cppm b/modules/RtAudio.cppm new file mode 100644 index 00000000..d3774dfa --- /dev/null +++ b/modules/RtAudio.cppm @@ -0,0 +1,29 @@ +module; + +#include "RtAudio.h" + +export module rt.audio; + +export +#ifdef RTAUDIO_USE_NAMESPACE +inline namespace rt { +inline namespace audio { +#else +namespace rt::audio { +#endif + using rt::audio::RtAudioFormat; + using rt::audio::RtAudioStreamFlags; + using rt::audio::RtAudioStreamStatus; + using rt::audio::RtAudioCallback; + using rt::audio::RtAudioErrorType; + using rt::audio::RtAudioErrorCallback; + using rt::audio::RtApi; + using rt::audio::RtAudio; + using rt::audio::ThreadHandle; + using rt::audio::StreamMutex; + using rt::audio::CallbackInfo; + using rt::audio::S24; +} +#ifdef RTAUDIO_USE_NAMESPACE +} +#endif