Merge remote-tracking branch 'upstream/pr/136'
authorStephen Sinclair <radarsat1@gmail.com>
Wed, 8 Aug 2018 14:30:51 +0000 (10:30 -0400)
committerStephen Sinclair <radarsat1@gmail.com>
Wed, 8 Aug 2018 14:30:51 +0000 (10:30 -0400)
RtAudio.cpp
RtAudio.h
rtaudio_c.cpp
rtaudio_c.h
tests/CMakeLists.txt
tests/Makefile.am
tests/apinames.cpp [new file with mode: 0644]

index a51608da9e3719ccd2205aa00b6f4d2ea3c3afda..728b4a3b34b9c5c975b7b3bd496d3bbc082f64da 100644 (file)
@@ -133,6 +133,147 @@ void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis )
 #endif
 }
 
+const std::string &RtAudio :: getCompiledApiName( RtAudio::Api api )
+{
+#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;
+}
+
+const std::string &RtAudio :: getCompiledApiDisplayName( RtAudio::Api api )
+{
+#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;
+}
+
+RtAudio::Api RtAudio :: getCompiledApiByName( const std::string &name )
+{
+  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;
+
+    ++api_number;
+  }
+
+  return RtAudio::UNSPECIFIED;
+}
+
 void RtAudio :: openRtApi( RtAudio::Api api )
 {
   if ( rtapi_ )
index 34a2534859fab7dcd85d4434d472209a09d1bbe4..449e0d7dcc9323b47b955ebc7c23a8b2187f4c45 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -397,6 +397,31 @@ class RTAUDIO_DLL_PUBLIC RtAudio
   */
   static void getCompiledApi( std::vector<RtAudio::Api> &apis );
 
+  //! Return the name of a specified compiled audio API.
+  /*!
+    This obtains a short lower-case name used for identification purposes.
+    This value is guaranteed to remain identical across library versions.
+    If the API is unknown or not compiled, this function will return
+    the empty string.
+  */
+  static const std::string &getCompiledApiName( RtAudio::Api api );
+
+  //! Return the display name of a specified compiled audio API.
+  /*!
+    This obtains a long name used for display purposes.
+    If the API is unknown or not compiled, this function will return
+    the empty string.
+  */
+  static const std::string &getCompiledApiDisplayName( RtAudio::Api api );
+
+  //! Return the compiled audio API having the given name.
+  /*!
+    A case insensitive comparison will check the specified name
+    against the list of compiled APIs, and return the one which
+    matches. On failure, the function returns UNSPECIFIED.
+  */
+  static RtAudio::Api getCompiledApiByName( const std::string &name );
+
   //! The class constructor.
   /*!
     The constructor performs minor initialization tasks.  An exception
index 699d2ce760d4fdd31b63d96a7b992f25d1e006ca..ec849414a4cdd6e860dccea76daa237018ac238c 100644 (file)
@@ -50,6 +50,25 @@ const char *rtaudio_version() { return RTAUDIO_VERSION; }
 
 const rtaudio_api_t *rtaudio_compiled_api() { return compiled_api; }
 
+const char *rtaudio_compiled_api_name(rtaudio_api_t api) {
+    const std::string &name = RtAudio::getCompiledApiName((RtAudio::Api)api);
+    return name.empty() ? NULL : name.c_str();
+}
+
+const char *rtaudio_compiled_api_display_name(rtaudio_api_t api)
+{
+    const std::string &name = RtAudio::getCompiledApiDisplayName((RtAudio::Api)api);
+    return name.empty() ? NULL : name.c_str();
+}
+
+rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) {
+    RtAudio::Api api = RtAudio::UNSPECIFIED;
+    if (name) {
+        api = RtAudio::getCompiledApiByName(name);
+    }
+    return (rtaudio_api_t)api;
+}
+
 const char *rtaudio_error(rtaudio_t audio) {
   if (audio->has_error) {
     return audio->errmsg;
index 05015a96cf35647ec737fd31b252a823e36cf7fa..893917cdb3a2fba7accb98d84108ac42c9371afc 100644 (file)
@@ -102,6 +102,9 @@ typedef struct rtaudio *rtaudio_t;
 
 RTAUDIOAPI const char *rtaudio_version(void);
 RTAUDIOAPI const rtaudio_api_t *rtaudio_compiled_api(void);
+RTAUDIOAPI const char *rtaudio_compiled_api_name(rtaudio_api_t api);
+RTAUDIOAPI const char *rtaudio_compiled_api_display_name(rtaudio_api_t api);
+RTAUDIOAPI rtaudio_api_t rtaudio_compiled_api_by_name(const char *name);
 
 RTAUDIOAPI const char *rtaudio_error(rtaudio_t audio);
 
index 5c08f6d3d71a90e9895c378ff04efaa85a3955f3..0040065b164a41e0065c4877c88c22001306bc7f 100644 (file)
@@ -20,6 +20,9 @@ target_link_libraries(record ${LIBRTAUDIO} ${LINKLIBS})
 add_executable(duplex duplex.cpp)
 target_link_libraries(duplex ${LIBRTAUDIO} ${LINKLIBS})
 
+add_executable(apinames apinames.cpp)
+target_link_libraries(apinames rtaudio_static ${LINKLIBS})
+
 add_executable(testall testall.cpp)
 target_link_libraries(testall ${LIBRTAUDIO} ${LINKLIBS})
 
index e39fdde25f9921215d41ce09546460e43355bb81..c8159da4c9bc569d48a492be3dbdb43fb7650ac2 100644 (file)
@@ -1,5 +1,5 @@
 
-noinst_PROGRAMS = audioprobe playsaw playraw record duplex testall teststops
+noinst_PROGRAMS = audioprobe playsaw playraw record duplex apinames testall teststops
 
 AM_CXXFLAGS = -Wall -I$(top_srcdir)
 
@@ -18,6 +18,9 @@ record_LDADD = $(top_builddir)/librtaudio.la
 duplex_SOURCES = duplex.cpp
 duplex_LDADD = $(top_builddir)/librtaudio.la
 
+apinames_SOURCES = apinames.cpp
+apinames_LDADD = $(top_builddir)/librtaudio.la
+
 testall_SOURCES = testall.cpp
 testall_LDADD = $(top_builddir)/librtaudio.la
 
diff --git a/tests/apinames.cpp b/tests/apinames.cpp
new file mode 100644 (file)
index 0000000..db7a258
--- /dev/null
@@ -0,0 +1,81 @@
+/******************************************/
+/*
+  apinames.cpp
+  by Jean Pierre Cimalando, 2018.
+
+  This program tests parts of RtAudio related
+  to API names, the conversion from name to API
+  and vice-versa.
+*/
+/******************************************/
+
+#include "RtAudio.h"
+#include <cctype>
+#include <cstdlib>
+#include <iostream>
+
+int main() {
+    std::vector<RtAudio::Api> apis;
+    RtAudio::getCompiledApi( apis );
+
+    // ensure the known APIs return valid names
+    std::cout << "API names by identifier:\n";
+    for ( size_t i = 0; i < apis.size() ; ++i ) {
+        const std::string &name = RtAudio::getCompiledApiName(apis[i]);
+        if (name.empty()) {
+            std::cerr << "Invalid name for API " << (int)apis[i] << "\n";
+            exit(1);
+        }
+        const std::string &displayName = RtAudio::getCompiledApiDisplayName(apis[i]);
+        if (displayName.empty()) {
+            std::cerr << "Invalid display name for API " << (int)apis[i] << "\n";
+            exit(1);
+        }
+        std::cout << "* " << (int)apis[i] << " '" << name << "': '" << displayName << "'\n";
+    }
+
+    // ensure unknown APIs return the empty string
+    {
+        const std::string &name = RtAudio::getCompiledApiName((RtAudio::Api)-1);
+        if (!name.empty()) {
+            std::cerr << "Bad string for invalid API\n";
+            exit(1);
+        }
+        const std::string &displayName = RtAudio::getCompiledApiDisplayName((RtAudio::Api)-1);
+        if (!displayName.empty()) {
+            std::cerr << "Bad display string for invalid API\n";
+            exit(1);
+        }
+    }
+
+    // try getting API identifier by name
+    std::cout << "API identifiers by name:\n";
+    for ( size_t i = 0; i < apis.size() ; ++i ) {
+        std::string name = RtAudio::getCompiledApiName(apis[i]);
+        if ( RtAudio::getCompiledApiByName(name) != apis[i] ) {
+            std::cerr << "Bad identifier for API '" << name << "'\n";
+            exit( 1 );
+        }
+        std::cout << "* '" << name << "': " << (int)apis[i] << "\n";
+
+        for ( size_t j = 0; j < name.size(); ++j )
+            name[j] = (j & 1) ? toupper(name[j]) : tolower(name[j]);
+        RtAudio::Api api = RtAudio::getCompiledApiByName(name);
+        if ( api != RtAudio::UNSPECIFIED ) {
+            std::cerr << "Identifier " << (int)api << " for invalid API '" << name << "'\n";
+            exit( 1 );
+        }
+    }
+
+    // try getting an API identifier by unknown name
+    {
+        RtAudio::Api api;
+        api = RtAudio::getCompiledApiByName("");
+        if ( api != RtAudio::UNSPECIFIED ) {
+            std::cerr << "Bad identifier for unknown API name\n";
+            exit( 1 );
+        }
+    }
+
+    return 0;
+}