return RTAUDIO_VERSION;
}
-// Define API names.
-// TODO: replace with initializer list in C++11.
+// Define API names and display names.
+// Must be in same order as API enum.
+extern "C" {
+const char* rtaudio_api_names[][2] = {
+ { "unspecified" , "Unknown" },
+ { "alsa" , "ALSA" },
+ { "pulse" , "Pulse" },
+ { "oss" , "OpenSoundSystem" },
+ { "jack" , "Jack" },
+ { "core" , "CoreAudio" },
+ { "wasapi" , "WASAPI" },
+ { "asio" , "ASIO" },
+ { "ds" , "DirectSound" },
+ { "dummy" , "Dummy" },
+};
+const unsigned int rtaudio_num_api_names =
+ sizeof(rtaudio_api_names)/sizeof(rtaudio_api_names[0]);
+
// 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<RtAudio::Api> > init_ApiNames()
-{
- RtAudio::ApiNameMap names;
- std::vector<RtAudio::Api> apis;
+RtAudio::Api rtaudio_compiled_apis[] = {
#if defined(__UNIX_JACK__)
- names["jack"] = std::pair<RtAudio::Api, std::string>(RtAudio::UNIX_JACK, "Jack");
- apis.push_back(RtAudio::UNIX_JACK);
+ RtAudio::UNIX_JACK,
#endif
#if defined(__LINUX_PULSE__)
- names["pulse"] = std::pair<RtAudio::Api, std::string>(RtAudio::LINUX_PULSE, "Pulse");
- apis.push_back(RtAudio::LINUX_PULSE);
+ RtAudio::LINUX_PULSE,
#endif
#if defined(__LINUX_ALSA__)
- names["alsa"] = std::pair<RtAudio::Api, std::string>(RtAudio::LINUX_ALSA, "ALSA");
- apis.push_back(RtAudio::LINUX_ALSA);
+ RtAudio::LINUX_ALSA,
#endif
#if defined(__LINUX_OSS__)
- names["oss"] = std::pair<RtAudio::Api, std::string>(RtAudio::LINUX_OSS, "OSS");
- apis.push_back(RtAudio::LINUX_OSS);
+ RtAudio::LINUX_OSS,
#endif
#if defined(__WINDOWS_ASIO__)
- names["asio"] = std::pair<RtAudio::Api, std::string>(RtAudio::WINDOWS_ASIO, "ASIO");
- apis.push_back(RtAudio::WINDOWS_ASIO);
+ RtAudio::WINDOWS_ASIO,
#endif
#if defined(__WINDOWS_WASAPI__)
- names["wasapi"] = std::pair<RtAudio::Api, std::string>(RtAudio::WINDOWS_WASAPI, "WASAPI");
- apis.push_back(RtAudio::WINDOWS_WASAPI);
+ RtAudio::WINDOWS_WASAPI,
#endif
#if defined(__WINDOWS_DS__)
- names["ds"] = std::pair<RtAudio::Api, std::string>(RtAudio::WINDOWS_DS, "DirectSound");
- apis.push_back(RtAudio::WINDOWS_DS);
+ RtAudio::WINDOWS_DS,
#endif
#if defined(__MACOSX_CORE__)
- names["core"] = std::pair<RtAudio::Api, std::string>(RtAudio::MACOSX_CORE, "CoreAudio");
- apis.push_back(RtAudio::MACOSX_CORE);
+ RtAudio::MACOSX_CORE,
#endif
#if defined(__RTAUDIO_DUMMY__)
- names["dummy"] = std::pair<RtAudio::Api, std::string>(RtAudio::RTAUDIO_DUMMY, "Dummy");
- apis.push_back(RtAudio::RTAUDIO_DUMMY);
+ RtAudio::RTAUDIO_DUMMY,
#endif
- return std::make_pair(names, apis);
+ RtAudio::UNSPECIFIED,
+};
+const unsigned int rtaudio_num_compiled_apis =
+ sizeof(rtaudio_compiled_apis)/sizeof(rtaudio_compiled_apis[0])-1;
}
-const RtAudio::ApiNameMap RtAudio::apiNames(init_ApiNames().first);
-const std::vector<RtAudio::Api> RtAudio::compiledApis(init_ApiNames().second);
+// TODO: replace this with something nicer (C++11)
+static const std::vector<RtAudio::Api> init_compiledApis() {
+ std::vector<RtAudio::Api> apis;
+ for (unsigned int i=0; i<rtaudio_num_compiled_apis; i++)
+ apis.push_back(rtaudio_compiled_apis[i]);
+ return apis;
+}
+const std::vector<RtAudio::Api> RtAudio::compiledApis(init_compiledApis());
+
+// This is a compile-time check that rtaudio_num_api_names == RtAudio::NUM_APIS.
+// If the build breaks here, check that they match.
+template<bool b> class StaticAssert { private: StaticAssert() {} };
+template<> class StaticAssert<true>{ public: StaticAssert() {} };
+class StaticAssertions { StaticAssertions() {
+ StaticAssert<rtaudio_num_api_names == RtAudio::NUM_APIS>();
+}};
void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis )
{
return compiledApis;
}
-static const std::string unknown_api_name = "";
-static const std::string unknown_api_display_name = "Unknown";
-
-const std::string& RtAudio :: getCompiledApiName( RtAudio::Api api )
+const std::string RtAudio :: getCompiledApiName( RtAudio::Api api )
{
- ApiNameMap::const_iterator it;
- for (it = apiNames.begin(); it != apiNames.end(); it++)
- if (it->second.first == api)
- return it->first;
- return unknown_api_name;
+ if (api < 0 || api > RtAudio::NUM_APIS
+ || (std::find(RtAudio::compiledApis.begin(),
+ RtAudio::compiledApis.end(), api) == RtAudio::compiledApis.end()))
+ return "";
+ return rtaudio_api_names[api][0];
}
-const std::string& RtAudio :: getCompiledApiDisplayName( RtAudio::Api api )
+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_api_display_name;
+ if (api < 0 || api > RtAudio::NUM_APIS
+ || (std::find(RtAudio::compiledApis.begin(),
+ RtAudio::compiledApis.end(), api) == RtAudio::compiledApis.end()))
+ return "Unknown";
+ return rtaudio_api_names[api][1];
}
RtAudio::Api RtAudio :: getCompiledApiByName( const std::string &name )
{
- if (apiNames.find(name) == apiNames.end())
- return RtAudio::UNSPECIFIED;
- return apiNames.at(name).first;
+ unsigned int i=0;
+ std::vector<RtAudio::Api>::const_iterator it;
+ for (it = compiledApis.begin(); it != compiledApis.end(); ++it, ++i)
+ if (name == rtaudio_api_names[*it][0])
+ return *it;
+ return RtAudio::UNSPECIFIED;
}
void RtAudio :: openRtApi( RtAudio::Api api )
#include <vector>
#include <stdexcept>
#include <iostream>
-#include <map>
/*! \typedef typedef unsigned long RtAudioFormat;
\brief RtAudio data format type.
WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
WINDOWS_DS, /*!< The Microsoft Direct Sound API. */
- RTAUDIO_DUMMY /*!< A compilable but non-functional API. */
+ RTAUDIO_DUMMY, /*!< A compilable but non-functional API. */
+ NUM_APIS /*!< Number of values in this enum. */
};
- //! Map string identifiers for APIs to enum identifiers and display names
- typedef std::map< std::string, std::pair<RtAudio::Api, std::string> > ApiNameMap;
-
//! The public device information structure for returning queried values.
struct DeviceInfo {
bool probed; /*!< true if the device capabilities were successfully probed. */
the enumerated list values. Note that there can be more than one
API compiled for certain operating systems.
*/
- static const std::vector<RtAudio::Api>& getCompiledApi();
+ static const std::vector<RtAudio::Api>& getCompiledApis();
//! Return the name of a specified compiled audio API.
/*!
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.
/*!
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.
/*!
protected:
- //! Storage for API name map
- static const ApiNameMap apiNames;
-
//! Storage for compiled API list
static const std::vector<RtAudio::Api> compiledApis;
char errmsg[MAX_ERROR_MESSAGE_LENGTH];
};
-static const rtaudio_api_t compiled_api[] = {
-#if defined(__UNIX_JACK__)
- RTAUDIO_API_UNIX_JACK,
-#endif
-#if defined(__LINUX_ALSA__)
- RTAUDIO_API_LINUX_ALSA,
-#endif
-#if defined(__LINUX_PULSE__)
- RTAUDIO_API_LINUX_PULSE,
-#endif
-#if defined(__LINUX_OSS__)
- RTAUDIO_API_LINUX_OSS,
-#endif
-#if defined(__WINDOWS_ASIO__)
- RTAUDIO_API_WINDOWS_ASIO,
-#endif
-#if defined(__WINDOWS_WASAPI__)
- RTAUDIO_API_WINDOWS_WASAPI,
-#endif
-#if defined(__WINDOWS_DS__)
- RTAUDIO_API_WINDOWS_DS,
-#endif
-#if defined(__MACOSX_CORE__)
- RTAUDIO_API_MACOSX_CORE,
-#endif
-#if defined(__RTAUDIO_DUMMY__)
- RTAUDIO_API_DUMMY,
-#endif
- RTAUDIO_API_UNSPECIFIED,
-};
-
const char *rtaudio_version() { return RTAUDIO_VERSION; }
-const rtaudio_api_t *rtaudio_compiled_api() { return compiled_api; }
+extern "C" const rtaudio_api_t rtaudio_compiled_apis[]; // casting from RtAudio::Api[]
+extern "C" unsigned int rtaudio_num_compiled_apis;
+const rtaudio_api_t *rtaudio_compiled_api() { return rtaudio_compiled_apis; }
+extern "C" const char* rtaudio_api_names[][2];
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();
+ if (api < 0 || api >= RTAUDIO_API_NUM)
+ return NULL;
+ return rtaudio_api_names[api][0];
}
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();
+ if (api < 0 || api >= RTAUDIO_API_NUM)
+ return "Unknown";
+ return rtaudio_api_names[api][1];
}
rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) {
RTAUDIO_API_WINDOWS_ASIO,
RTAUDIO_API_WINDOWS_DS,
RTAUDIO_API_DUMMY,
+ RTAUDIO_API_NUM,
} rtaudio_api_t;
#define NUM_SAMPLE_RATES 16
#include <cstdlib>
#include <iostream>
-int main() {
+int test_cpp() {
std::vector<RtAudio::Api> apis;
RtAudio::getCompiledApi( apis );
// ensure the known APIs return valid names
- std::cout << "API names by identifier:\n";
+ std::cout << "API names by identifier (C++):\n";
for ( size_t i = 0; i < apis.size() ; ++i ) {
- const std::string &name = RtAudio::getCompiledApiName(apis[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]);
+ const std::string displayName = RtAudio::getCompiledApiDisplayName(apis[i]);
if (displayName.empty()) {
std::cerr << "Invalid display name for API " << (int)apis[i] << "\n";
exit(1);
// ensure unknown APIs return the empty string
{
- const std::string &name = RtAudio::getCompiledApiName((RtAudio::Api)-1);
+ const std::string name = RtAudio::getCompiledApiName((RtAudio::Api)-1);
if (!name.empty()) {
std::cerr << "Bad string for invalid API '" << name << "'\n";
exit(1);
}
- const std::string &displayName = RtAudio::getCompiledApiDisplayName((RtAudio::Api)-1);
+ const std::string displayName = RtAudio::getCompiledApiDisplayName((RtAudio::Api)-1);
if (displayName!="Unknown") {
std::cerr << "Bad display string for invalid API '" << displayName << "'\n";
exit(1);
}
// try getting API identifier by name
- std::cout << "API identifiers by name:\n";
+ std::cout << "API identifiers by name (C++):\n";
for ( size_t i = 0; i < apis.size() ; ++i ) {
std::string name = RtAudio::getCompiledApiName(apis[i]);
if ( RtAudio::getCompiledApiByName(name) != apis[i] ) {
return 0;
}
+
+#include "rtaudio_c.h"
+
+int test_c() {
+ const rtaudio_api_t *apis = rtaudio_compiled_api();
+
+ // ensure the known APIs return valid names
+ std::cout << "API names by identifier (C):\n";
+ for ( size_t i = 0; apis[i] != RTAUDIO_API_UNSPECIFIED; ++i) {
+ const std::string name = rtaudio_compiled_api_name(apis[i]);
+ if (name.empty()) {
+ std::cerr << "Invalid name for API " << (int)apis[i] << "\n";
+ exit(1);
+ }
+ const std::string displayName = rtaudio_compiled_api_display_name(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 char *s = rtaudio_compiled_api_name((rtaudio_api_t)-1);
+ const std::string name(s?s:"");
+ if (!name.empty()) {
+ std::cerr << "Bad string for invalid API '" << name << "'\n";
+ exit(1);
+ }
+ s = rtaudio_compiled_api_display_name((rtaudio_api_t)-1);
+ const std::string displayName(s?s:"");
+ if (displayName!="Unknown") {
+ std::cerr << "Bad display string for invalid API '" << displayName << "'\n";
+ exit(1);
+ }
+ }
+
+ // try getting API identifier by name
+ std::cout << "API identifiers by name (C):\n";
+ for ( size_t i = 0; apis[i] != RTAUDIO_API_UNSPECIFIED ; ++i ) {
+ const char *s = rtaudio_compiled_api_name(apis[i]);
+ std::string name(s?s:"");
+ if ( rtaudio_compiled_api_by_name(name.c_str()) != 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_t api = rtaudio_compiled_api_by_name(name.c_str());
+ if ( api != RTAUDIO_API_UNSPECIFIED ) {
+ std::cerr << "Identifier " << (int)api << " for invalid API '" << name << "'\n";
+ exit( 1 );
+ }
+ }
+
+ // try getting an API identifier by unknown name
+ {
+ rtaudio_api_t api;
+ api = rtaudio_compiled_api_by_name("");
+ if ( api != RTAUDIO_API_UNSPECIFIED ) {
+ std::cerr << "Bad identifier for unknown API name\n";
+ exit( 1 );
+ }
+ }
+
+ return 0;
+}
+
+int main()
+{
+ test_cpp();
+ test_c();
+}