From: Stephen Sinclair Date: Wed, 8 Aug 2018 15:55:39 +0000 (-0400) Subject: Use a map for API names X-Git-Url: https://git.carlh.net/gitweb/?p=rtaudio-cdist.git;a=commitdiff_plain;h=3d054aec68641b049c102d20632a1eb618355a6f Use a map for API names --- diff --git a/RtAudio.cpp b/RtAudio.cpp index 728b4a3..7b7c8ef 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -98,180 +98,91 @@ std::string RtAudio :: getVersion( void ) return RTAUDIO_VERSION; } -void RtAudio :: getCompiledApi( std::vector &apis ) -{ - apis.clear(); - - // The order here will control the order of RtAudio's API search in - // the constructor. +// Define API names. +// TODO: replace with initializer list in C++11. +// The order here will control the order of RtAudio's API search in +// the constructor. +// Have to maintain a separate list of API enum identifiers since map +// doesn't preserve insertion order. +static std::pair< RtAudio::ApiNameMap, std::vector > init_ApiNames() +{ + RtAudio::ApiNameMap names; + std::vector apis; #if defined(__UNIX_JACK__) - apis.push_back( UNIX_JACK ); + names["jack"] = std::pair(RtAudio::UNIX_JACK, "Jack"); + apis.push_back(RtAudio::UNIX_JACK); #endif #if defined(__LINUX_PULSE__) - apis.push_back( LINUX_PULSE ); + names["pulse"] = std::pair(RtAudio::LINUX_PULSE, "Pulse"); + apis.push_back(RtAudio::LINUX_PULSE); #endif #if defined(__LINUX_ALSA__) - apis.push_back( LINUX_ALSA ); + names["alsa"] = std::pair(RtAudio::LINUX_ALSA, "ALSA"); + apis.push_back(RtAudio::LINUX_ALSA); #endif #if defined(__LINUX_OSS__) - apis.push_back( LINUX_OSS ); + names["oss"] = std::pair(RtAudio::LINUX_OSS, "OSS"); + apis.push_back(RtAudio::LINUX_OSS); #endif #if defined(__WINDOWS_ASIO__) - apis.push_back( WINDOWS_ASIO ); + names["asio"] = std::pair(RtAudio::WINDOWS_ASIO, "ASIO"); + apis.push_back(RtAudio::WINDOWS_ASIO); #endif #if defined(__WINDOWS_WASAPI__) - apis.push_back( WINDOWS_WASAPI ); + names["wasapi"] = std::pair(RtAudio::WINDOWS_WASAPI, "WASAPI"); + apis.push_back(RtAudio::WINDOWS_WASAPI); #endif #if defined(__WINDOWS_DS__) - apis.push_back( WINDOWS_DS ); + names["ds"] = std::pair(RtAudio::WINDOWS_DS, "DirectSound"); + apis.push_back(RtAudio::WINDOWS_DS); #endif #if defined(__MACOSX_CORE__) - apis.push_back( MACOSX_CORE ); + names["core"] = std::pair(RtAudio::MACOSX_CORE, "CoreAudio"); + apis.push_back(RtAudio::MACOSX_CORE); #endif #if defined(__RTAUDIO_DUMMY__) - apis.push_back( RTAUDIO_DUMMY ); + names["dummy"] = std::pair(RtAudio::RTAUDIO_DUMMY, "Dummy"); + apis.push_back(RtAudio::RTAUDIO_DUMMY); #endif + return std::make_pair(names, apis); } -const std::string &RtAudio :: getCompiledApiName( RtAudio::Api api ) +const RtAudio::ApiNameMap RtAudio::apiNames(init_ApiNames().first); +const std::vector RtAudio::compiledApis(init_ApiNames().second); + +void RtAudio :: getCompiledApi( std::vector &apis ) { -#if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) { - static std::string name( "jack" ); - return name; - } -#endif -#if defined(__LINUX_PULSE__) - if ( api == LINUX_PULSE ) { - static std::string name( "pulse" ); - return name; - } -#endif -#if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) { - static std::string name( "alsa" ); - return name; - } -#endif -#if defined(__LINUX_OSS__) - if ( api == LINUX_OSS ) { - static std::string name( "oss" ); - return name; - } -#endif -#if defined(__WINDOWS_ASIO__) - if ( api == WINDOWS_ASIO ) { - static std::string name( "asio" ); - return name; - } -#endif -#if defined(__WINDOWS_WASAPI__) - if ( api == WINDOWS_WASAPI ) { - static std::string name( "wasapi" ); - return name; - } -#endif -#if defined(__WINDOWS_DS__) - if ( api == WINDOWS_DS ) { - static std::string name( "ds" ); - return name; - } -#endif -#if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) { - static std::string name( "core" ); - return name; - } -#endif -#if defined(__RTAUDIO_DUMMY__) - if ( api == RTAUDIO_DUMMY ) { - static std::string name( "dummy" ); - return name; - } -#endif - static std::string name; - return name; + apis = compiledApis; } -const std::string &RtAudio :: getCompiledApiDisplayName( RtAudio::Api api ) +const std::vector& RtAudio :: getCompiledApi() { -#if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) { - static std::string name( "JACK" ); - return name; - } -#endif -#if defined(__LINUX_PULSE__) - if ( api == LINUX_PULSE ) { - static std::string name( "PulseAudio" ); - return name; - } -#endif -#if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) { - static std::string name( "ALSA" ); - return name; - } -#endif -#if defined(__LINUX_OSS__) - if ( api == LINUX_OSS ) { - static std::string name( "OSS" ); - return name; - } -#endif -#if defined(__WINDOWS_ASIO__) - if ( api == WINDOWS_ASIO ) { - static std::string name( "ASIO" ); - return name; - } -#endif -#if defined(__WINDOWS_WASAPI__) - if ( api == WINDOWS_WASAPI ) { - static std::string name( "WASAPI" ); - return name; - } -#endif -#if defined(__WINDOWS_DS__) - if ( api == WINDOWS_DS ) { - static std::string name( "DirectSound" ); - return name; - } -#endif -#if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) { - static std::string name( "Core Audio" ); - return name; - } -#endif -#if defined(__RTAUDIO_DUMMY__) - if ( api == RTAUDIO_DUMMY ) { - static std::string name( "RtAudio Dummy" ); - return name; - } -#endif - static std::string name; - return name; + return compiledApis; } -RtAudio::Api RtAudio :: getCompiledApiByName( const std::string &name ) +const std::string RtAudio :: getCompiledApiName( RtAudio::Api api ) { - unsigned int api_number = RtAudio::UNSPECIFIED; - size_t nameLength = name.size(); - - if ( nameLength == 0 ) - return RtAudio::UNSPECIFIED; - - while ( api_number <= RtAudio::RTAUDIO_DUMMY ) { - const std::string &otherName = - getCompiledApiName((RtAudio::Api)api_number); - - if ( name == otherName ) - return (RtAudio::Api)api_number; + ApiNameMap::const_iterator it; + for (it = apiNames.begin(); it != apiNames.end(); it++) + if (it->second.first == api) + return it->first; + return ""; +} - ++api_number; - } +const std::string RtAudio :: getCompiledApiDisplayName( RtAudio::Api api ) +{ + ApiNameMap::const_iterator it; + for (it = apiNames.begin(); it != apiNames.end(); it++) + if (it->second.first == api) + return it->second.second; + return "Unknown"; +} - return RtAudio::UNSPECIFIED; +RtAudio::Api RtAudio :: getCompiledApiByName( const std::string &name ) +{ + if (apiNames.find(name) == apiNames.end()) + return RtAudio::UNSPECIFIED; + return apiNames.at(name).first; } void RtAudio :: openRtApi( RtAudio::Api api ) diff --git a/RtAudio.h b/RtAudio.h index 449e0d7..78d96a9 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -61,6 +61,7 @@ #include #include #include +#include /*! \typedef typedef unsigned long RtAudioFormat; \brief RtAudio data format type. @@ -288,6 +289,9 @@ class RTAUDIO_DLL_PUBLIC RtAudio RTAUDIO_DUMMY /*!< A compilable but non-functional API. */ }; + //! Map string identifiers for APIs to enum identifiers and display names + typedef std::map< std::string, std::pair > ApiNameMap; + //! The public device information structure for returning queried values. struct DeviceInfo { bool probed; /*!< true if the device capabilities were successfully probed. */ @@ -397,6 +401,14 @@ class RTAUDIO_DLL_PUBLIC RtAudio */ static void getCompiledApi( std::vector &apis ); + //! A static function to determine the available compiled audio APIs. + /*! + The values returned in the std::vector can be compared against + the enumerated list values. Note that there can be more than one + API compiled for certain operating systems. + */ + static const std::vector& getCompiledApi(); + //! Return the name of a specified compiled audio API. /*! This obtains a short lower-case name used for identification purposes. @@ -404,7 +416,7 @@ class RTAUDIO_DLL_PUBLIC RtAudio If the API is unknown or not compiled, this function will return the empty string. */ - static const std::string &getCompiledApiName( RtAudio::Api api ); + static const std::string getCompiledApiName( RtAudio::Api api ); //! Return the display name of a specified compiled audio API. /*! @@ -412,7 +424,7 @@ class RTAUDIO_DLL_PUBLIC RtAudio If the API is unknown or not compiled, this function will return the empty string. */ - static const std::string &getCompiledApiDisplayName( RtAudio::Api api ); + static const std::string getCompiledApiDisplayName( RtAudio::Api api ); //! Return the compiled audio API having the given name. /*! @@ -606,6 +618,12 @@ class RTAUDIO_DLL_PUBLIC RtAudio protected: + //! Storage for API name map + static const ApiNameMap apiNames; + + //! Storage for compiled API list + static const std::vector compiledApis; + void openRtApi( RtAudio::Api api ); RtApi *rtapi_; }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0040065..5847027 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,7 +21,7 @@ add_executable(duplex duplex.cpp) target_link_libraries(duplex ${LIBRTAUDIO} ${LINKLIBS}) add_executable(apinames apinames.cpp) -target_link_libraries(apinames rtaudio_static ${LINKLIBS}) +target_link_libraries(apinames ${LIBRTAUDIO} ${LINKLIBS}) add_executable(testall testall.cpp) target_link_libraries(testall ${LIBRTAUDIO} ${LINKLIBS}) diff --git a/tests/apinames.cpp b/tests/apinames.cpp index db7a258..81a3d7d 100644 --- a/tests/apinames.cpp +++ b/tests/apinames.cpp @@ -38,12 +38,12 @@ int main() { { const std::string &name = RtAudio::getCompiledApiName((RtAudio::Api)-1); if (!name.empty()) { - std::cerr << "Bad string for invalid API\n"; + std::cerr << "Bad string for invalid API '" << name << "'\n"; exit(1); } const std::string &displayName = RtAudio::getCompiledApiDisplayName((RtAudio::Api)-1); - if (!displayName.empty()) { - std::cerr << "Bad display string for invalid API\n"; + if (displayName!="Unknown") { + std::cerr << "Bad display string for invalid API '" << displayName << "'\n"; exit(1); } }