@@ -45,6 +45,7 @@ | |||||
#include <cstdlib> | #include <cstdlib> | ||||
#include <cstring> | #include <cstring> | ||||
#include <climits> | #include <climits> | ||||
#include <cctype> | |||||
#include <cmath> | #include <cmath> | ||||
#include <algorithm> | #include <algorithm> | ||||
@@ -133,6 +134,92 @@ void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) | |||||
#endif | #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( "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( "CoreAudio" ); | |||||
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; | |||||
} | |||||
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); | |||||
bool equal = nameLength == otherName.size(); | |||||
for ( size_t i = 0; equal && i < nameLength; ++i ) | |||||
equal = tolower((unsigned char)name[i]) == | |||||
tolower((unsigned char)otherName[i]); | |||||
if ( equal ) | |||||
return (RtAudio::Api)api_number; | |||||
++api_number; | |||||
} | |||||
return RtAudio::UNSPECIFIED; | |||||
} | |||||
void RtAudio :: openRtApi( RtAudio::Api api ) | void RtAudio :: openRtApi( RtAudio::Api api ) | ||||
{ | { | ||||
if ( rtapi_ ) | if ( rtapi_ ) | ||||
@@ -397,6 +397,21 @@ class RTAUDIO_DLL_PUBLIC RtAudio | |||||
*/ | */ | ||||
static void getCompiledApi( std::vector<RtAudio::Api> &apis ); | static void getCompiledApi( std::vector<RtAudio::Api> &apis ); | ||||
//! 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 ); | |||||
//! 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 class constructor. | ||||
/*! | /*! | ||||
The constructor performs minor initialization tasks. An exception | The constructor performs minor initialization tasks. An exception | ||||
@@ -18,6 +18,9 @@ target_link_libraries(record rtaudio_static ${LINKLIBS}) | |||||
add_executable(duplex duplex.cpp) | add_executable(duplex duplex.cpp) | ||||
target_link_libraries(duplex rtaudio_static ${LINKLIBS}) | target_link_libraries(duplex rtaudio_static ${LINKLIBS}) | ||||
add_executable(apinames apinames.cpp) | |||||
target_link_libraries(apinames rtaudio_static ${LINKLIBS}) | |||||
add_executable(testall testall.cpp) | add_executable(testall testall.cpp) | ||||
target_link_libraries(testall rtaudio_static ${LINKLIBS}) | target_link_libraries(testall rtaudio_static ${LINKLIBS}) | ||||
@@ -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) | AM_CXXFLAGS = -Wall -I$(top_srcdir) | ||||
@@ -18,6 +18,9 @@ record_LDADD = $(top_builddir)/librtaudio.la | |||||
duplex_SOURCES = duplex.cpp | duplex_SOURCES = duplex.cpp | ||||
duplex_LDADD = $(top_builddir)/librtaudio.la | duplex_LDADD = $(top_builddir)/librtaudio.la | ||||
apinames_SOURCES = apinames.cpp | |||||
apinames_LDADD = $(top_builddir)/librtaudio.la | |||||
testall_SOURCES = testall.cpp | testall_SOURCES = testall.cpp | ||||
testall_LDADD = $(top_builddir)/librtaudio.la | testall_LDADD = $(top_builddir)/librtaudio.la | ||||
@@ -0,0 +1,75 @@ | |||||
/******************************************/ | |||||
/* | |||||
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 <cstdlib> | |||||
#include <cctype> | |||||
#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); | |||||
} | |||||
std::cout << "* " << (int)apis[i] << ": '" << name << "'\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); | |||||
} | |||||
} | |||||
// try getting API identifier by case-insensitive 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]); | |||||
if ( RtAudio::getCompiledApiByName(name) != apis[i] ) { | |||||
std::cerr << "Bad identifier for API '" << name << "'\n"; | |||||
exit( 1 ); | |||||
} | |||||
std::cout << "* '" << name << "': " << (int)apis[i] << "\n"; | |||||
} | |||||
// try getting an API identifier by unknown name | |||||
{ | |||||
RtAudio::Api api; | |||||
api = RtAudio::getCompiledApiByName("ALSO"); | |||||
if ( api != RtAudio::UNSPECIFIED ) { | |||||
std::cerr << "Bad identifier for unknown API name\n"; | |||||
exit( 1 ); | |||||
} | |||||
api = RtAudio::getCompiledApiByName(""); | |||||
if ( api != RtAudio::UNSPECIFIED ) { | |||||
std::cerr << "Bad identifier for unknown API name\n"; | |||||
exit( 1 ); | |||||
} | |||||
} | |||||
return 0; | |||||
} |