From e6257fd0bc2c563fe1d0b8b645e9cb5c465d4d8d Mon Sep 17 00:00:00 2001 From: Toyosatomimi no Miko <110693261+mikomikotaishi@users.noreply.github.com> Date: Thu, 23 Oct 2025 22:21:33 -0400 Subject: [PATCH 1/4] Add C++20 modules support --- CMakeLists.txt | 13 +++++++++++++ README.md | 2 ++ RtAudio.cpp | 4 ++++ RtAudio.h | 15 +++++++++++++++ modules/CMakeLists.txt | 32 ++++++++++++++++++++++++++++++++ modules/RtAudio.cppm | 26 ++++++++++++++++++++++++++ rtaudio_c.cpp | 4 ++-- rtaudio_c.h | 2 +- 8 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 modules/CMakeLists.txt create mode 100644 modules/RtAudio.cppm diff --git a/CMakeLists.txt b/CMakeLists.txt index 75d549f9..369f7256 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 "Use namespace rtaudio for module" 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..b643230c 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 rtaudio;`. Namespaces are inlined, so classes can be accessed through namespace `rtaudio` or through the global namespace (for example, `rtaudio::RtApi` and `::RtApi` are both valid). + ## Building Several build systems are available. These are: diff --git a/RtAudio.cpp b/RtAudio.cpp index 8e394be8..7359b0a0 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -55,6 +55,8 @@ #include #endif +inline namespace rtaudio { + // Static variable definitions. const unsigned int RtApi::MAX_SAMPLE_RATES = 14; const unsigned int RtApi::SAMPLE_RATES[] = { @@ -11550,6 +11552,8 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat ptr += 5; } } +} + } // Indentation settings for Vim and Emacs diff --git a/RtAudio.h b/RtAudio.h index ec71d9d0..a7cba59a 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -85,6 +85,8 @@ #include #include +inline namespace rtaudio { + /*! \typedef typedef unsigned long RtAudioFormat; \brief RtAudio data format type. @@ -648,6 +650,8 @@ class RTAUDIO_DLL_PUBLIC RtAudio std::shared_ptr rtapi_; }; +} + // Operating system dependent thread functionality. #if defined(_MSC_VER) @@ -658,16 +662,20 @@ class RTAUDIO_DLL_PUBLIC RtAudio #include #include +inline namespace rtaudio { typedef uintptr_t ThreadHandle; typedef CRITICAL_SECTION StreamMutex; +} #else // Using pthread library for various flavors of unix. #include +inline namespace rtaudio { typedef pthread_t ThreadHandle; typedef pthread_mutex_t StreamMutex; +} #endif @@ -680,6 +688,8 @@ class RTAUDIO_DLL_PUBLIC RtAudio #endif +inline namespace rtaudio { + // This global structure type is used to pass callback information // between the private RtAudio stream structure and global callback // handling functions. @@ -738,12 +748,15 @@ class S24 { }; #pragma pack(pop) +} + #if defined( HAVE_GETTIMEOFDAY ) #include #endif #include +inline namespace rtaudio { class RTAUDIO_DLL_PUBLIC RtApi { public: @@ -931,6 +944,8 @@ 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..d2014b8a --- /dev/null +++ b/modules/RtAudio.cppm @@ -0,0 +1,26 @@ +module; + +#ifdef RTAUDIO_USE_NAMESPACE +#define RTAUDIO_NAMESPACE_INLINE inline +#else +#define RTAUDIO_NAMESPACE_INLINE +#endif + +#include "RtAudio.h" + +export module rtaudio; + +export RTAUDIO_NAMESPACE_INLINE namespace rtaudio { + using rtaudio::RtAudioFormat; + using rtaudio::RtAudioStreamFlags; + using rtaudio::RtAudioStreamStatus; + using rtaudio::RtAudioCallback; + using rtaudio::RtAudioErrorType; + using rtaudio::RtAudioErrorCallback; + using rtaudio::RtApi; + using rtaudio::RtAudio; + using rtaudio::ThreadHandle; + using rtaudio::StreamMutex; + using rtaudio::CallbackInfo; + using rtaudio::S24; +} diff --git a/rtaudio_c.cpp b/rtaudio_c.cpp index 9cfa4586..8e663477 100644 --- a/rtaudio_c.cpp +++ b/rtaudio_c.cpp @@ -5,7 +5,7 @@ #define MAX_ERROR_MESSAGE_LENGTH 512 -struct rtaudio { +struct rtaudio_struct { RtAudio *audio; rtaudio_error_t errtype; @@ -58,7 +58,7 @@ rtaudio_error_t rtaudio_error_type(rtaudio_t audio) { } rtaudio_t rtaudio_create(rtaudio_api_t api) { - rtaudio_t audio = new struct rtaudio(); + rtaudio_t audio = new struct rtaudio_struct(); audio->errtype = RTAUDIO_ERROR_NONE; audio->audio = new RtAudio((RtAudio::Api)api, [audio](RtAudioErrorType type, const std::string &errorText){ diff --git a/rtaudio_c.h b/rtaudio_c.h index 7aa69d95..c147da65 100644 --- a/rtaudio_c.h +++ b/rtaudio_c.h @@ -192,7 +192,7 @@ typedef struct rtaudio_stream_options { char name[MAX_NAME_LENGTH]; } rtaudio_stream_options_t; -typedef struct rtaudio *rtaudio_t; +typedef struct rtaudio_struct *rtaudio_t; //! Determine the current RtAudio version. See \ref RtAudio::getVersion(). RTAUDIOAPI const char *rtaudio_version(void); From 1162ae39d1b9ed2ff564aba6471d588b89ba50d2 Mon Sep 17 00:00:00 2001 From: Toyosatomimi no Miko <110693261+mikomikotaishi@users.noreply.github.com> Date: Thu, 23 Oct 2025 22:55:21 -0400 Subject: [PATCH 2/4] Break namespace into rt::audio --- README.md | 2 +- RtAudio.cpp | 4 +++- RtAudio.h | 21 ++++++++++++++++----- modules/RtAudio.cppm | 43 +++++++++++++++++++++++-------------------- rtaudio_c.cpp | 4 ++-- rtaudio_c.h | 2 +- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index b643230c..28e41da1 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ 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 rtaudio;`. Namespaces are inlined, so classes can be accessed through namespace `rtaudio` or through the global namespace (for example, `rtaudio::RtApi` and `::RtApi` are both valid). +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 diff --git a/RtAudio.cpp b/RtAudio.cpp index 7359b0a0..2bd93641 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -55,7 +55,8 @@ #include #endif -inline namespace rtaudio { +inline namespace rt { +inline namespace audio { // Static variable definitions. const unsigned int RtApi::MAX_SAMPLE_RATES = 14; @@ -11554,6 +11555,7 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat } } +} } // Indentation settings for Vim and Emacs diff --git a/RtAudio.h b/RtAudio.h index a7cba59a..a11c6232 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -85,7 +85,8 @@ #include #include -inline namespace rtaudio { +inline namespace rt { +inline namespace audio { /*! \typedef typedef unsigned long RtAudioFormat; \brief RtAudio data format type. @@ -650,6 +651,7 @@ class RTAUDIO_DLL_PUBLIC RtAudio std::shared_ptr rtapi_; }; +} } // Operating system dependent thread functionality. @@ -662,20 +664,24 @@ class RTAUDIO_DLL_PUBLIC RtAudio #include #include -inline namespace rtaudio { +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 rtaudio { +inline namespace rt { +inline namespace audio { typedef pthread_t ThreadHandle; typedef pthread_mutex_t StreamMutex; } +} #endif @@ -688,7 +694,8 @@ inline namespace rtaudio { #endif -inline namespace rtaudio { +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 @@ -748,6 +755,7 @@ class S24 { }; #pragma pack(pop) +} } #if defined( HAVE_GETTIMEOFDAY ) @@ -756,7 +764,9 @@ class S24 { #include -inline namespace rtaudio { +inline namespace rt { +inline namespace audio { + class RTAUDIO_DLL_PUBLIC RtApi { public: @@ -944,6 +954,7 @@ inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value #endif +} } // Indentation settings for Vim and Emacs diff --git a/modules/RtAudio.cppm b/modules/RtAudio.cppm index d2014b8a..d3774dfa 100644 --- a/modules/RtAudio.cppm +++ b/modules/RtAudio.cppm @@ -1,26 +1,29 @@ module; -#ifdef RTAUDIO_USE_NAMESPACE -#define RTAUDIO_NAMESPACE_INLINE inline -#else -#define RTAUDIO_NAMESPACE_INLINE -#endif - #include "RtAudio.h" -export module rtaudio; +export module rt.audio; -export RTAUDIO_NAMESPACE_INLINE namespace rtaudio { - using rtaudio::RtAudioFormat; - using rtaudio::RtAudioStreamFlags; - using rtaudio::RtAudioStreamStatus; - using rtaudio::RtAudioCallback; - using rtaudio::RtAudioErrorType; - using rtaudio::RtAudioErrorCallback; - using rtaudio::RtApi; - using rtaudio::RtAudio; - using rtaudio::ThreadHandle; - using rtaudio::StreamMutex; - using rtaudio::CallbackInfo; - using rtaudio::S24; +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 diff --git a/rtaudio_c.cpp b/rtaudio_c.cpp index 8e663477..9cfa4586 100644 --- a/rtaudio_c.cpp +++ b/rtaudio_c.cpp @@ -5,7 +5,7 @@ #define MAX_ERROR_MESSAGE_LENGTH 512 -struct rtaudio_struct { +struct rtaudio { RtAudio *audio; rtaudio_error_t errtype; @@ -58,7 +58,7 @@ rtaudio_error_t rtaudio_error_type(rtaudio_t audio) { } rtaudio_t rtaudio_create(rtaudio_api_t api) { - rtaudio_t audio = new struct rtaudio_struct(); + rtaudio_t audio = new struct rtaudio(); audio->errtype = RTAUDIO_ERROR_NONE; audio->audio = new RtAudio((RtAudio::Api)api, [audio](RtAudioErrorType type, const std::string &errorText){ diff --git a/rtaudio_c.h b/rtaudio_c.h index c147da65..7aa69d95 100644 --- a/rtaudio_c.h +++ b/rtaudio_c.h @@ -192,7 +192,7 @@ typedef struct rtaudio_stream_options { char name[MAX_NAME_LENGTH]; } rtaudio_stream_options_t; -typedef struct rtaudio_struct *rtaudio_t; +typedef struct rtaudio *rtaudio_t; //! Determine the current RtAudio version. See \ref RtAudio::getVersion(). RTAUDIOAPI const char *rtaudio_version(void); From 73234aa51d7f7aa0788ce2d3a4be688830494568 Mon Sep 17 00:00:00 2001 From: Toyosatomimi no Miko <110693261+mikomikotaishi@users.noreply.github.com> Date: Thu, 23 Oct 2025 23:00:12 -0400 Subject: [PATCH 3/4] Update description of CMake option --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 369f7256..75c4a0f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ endif () # Module options option(RTAUDIO_BUILD_MODULES "Build C++ modules for RtAudio" OFF) -option(RTAUDIO_USE_NAMESPACE "Use namespace rtaudio for module" ON) +option(RTAUDIO_USE_NAMESPACE "Force usage of namespace rt::audio for modules" ON) # Add -Wall if possible if (CMAKE_COMPILER_IS_GNUCXX) From 4a5e918dee6aa0779d7266b27931d63fe4ec7587 Mon Sep 17 00:00:00 2001 From: Toyosatomimi no Miko <110693261+mikomikotaishi@users.noreply.github.com> Date: Mon, 27 Oct 2025 19:27:49 -0400 Subject: [PATCH 4/4] Remove namespaces from source file --- RtAudio.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/RtAudio.cpp b/RtAudio.cpp index 2bd93641..8e394be8 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -55,9 +55,6 @@ #include #endif -inline namespace rt { -inline namespace audio { - // Static variable definitions. const unsigned int RtApi::MAX_SAMPLE_RATES = 14; const unsigned int RtApi::SAMPLE_RATES[] = { @@ -11555,9 +11552,6 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat } } -} -} - // Indentation settings for Vim and Emacs // // Local Variables: