Browse Source

Merge remote-tracking branch 'upstream/pr/136'

tags/5.1.0
Stephen Sinclair 5 years ago
parent
commit
4690b26068
9 changed files with 299 additions and 49 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +1
    -0
      Makefile.am
  3. +70
    -14
      RtAudio.cpp
  4. +30
    -2
      RtAudio.h
  5. +25
    -32
      rtaudio_c.cpp
  6. +8
    -0
      rtaudio_c.h
  7. +3
    -0
      tests/CMakeLists.txt
  8. +4
    -1
      tests/Makefile.am
  9. +157
    -0
      tests/apinames.cpp

+ 1
- 0
CMakeLists.txt View File

@@ -216,6 +216,7 @@ if(BUILD_SHARED_LIBS)

# Set compile-time definitions
target_compile_definitions(rtaudio PRIVATE ${API_DEFS})
target_compile_definitions(rtaudio PRIVATE RTAUDIO_EXPORT)

target_link_libraries(rtaudio ${LINKLIBS})
endif()


+ 1
- 0
Makefile.am View File

@@ -6,6 +6,7 @@ endif
AM_CXXFLAGS = @visibility@

lib_LTLIBRARIES = %D%/librtaudio.la
%C%_librtaudio_la_CXXFLAGS = -DRTAUDIO_EXPORT
%C%_librtaudio_la_LDFLAGS = -no-undefined -export-dynamic -version-info @SO_VERSION@
%C%_librtaudio_la_SOURCES = \
%D%/RtAudio.cpp \


+ 70
- 14
RtAudio.cpp View File

@@ -98,39 +98,95 @@ std::string RtAudio :: getVersion( void )
return RTAUDIO_VERSION;
}

void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis )
{
apis.clear();
// 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.
// The order here will control the order of RtAudio's API search in
// the constructor.
extern "C" const RtAudio::Api rtaudio_compiled_apis[] = {
#if defined(__UNIX_JACK__)
apis.push_back( UNIX_JACK );
RtAudio::UNIX_JACK,
#endif
#if defined(__LINUX_PULSE__)
apis.push_back( LINUX_PULSE );
RtAudio::LINUX_PULSE,
#endif
#if defined(__LINUX_ALSA__)
apis.push_back( LINUX_ALSA );
RtAudio::LINUX_ALSA,
#endif
#if defined(__LINUX_OSS__)
apis.push_back( LINUX_OSS );
RtAudio::LINUX_OSS,
#endif
#if defined(__WINDOWS_ASIO__)
apis.push_back( WINDOWS_ASIO );
RtAudio::WINDOWS_ASIO,
#endif
#if defined(__WINDOWS_WASAPI__)
apis.push_back( WINDOWS_WASAPI );
RtAudio::WINDOWS_WASAPI,
#endif
#if defined(__WINDOWS_DS__)
apis.push_back( WINDOWS_DS );
RtAudio::WINDOWS_DS,
#endif
#if defined(__MACOSX_CORE__)
apis.push_back( MACOSX_CORE );
RtAudio::MACOSX_CORE,
#endif
#if defined(__RTAUDIO_DUMMY__)
apis.push_back( RTAUDIO_DUMMY );
RtAudio::RTAUDIO_DUMMY,
#endif
RtAudio::UNSPECIFIED,
};
extern "C" const unsigned int rtaudio_num_compiled_apis =
sizeof(rtaudio_compiled_apis)/sizeof(rtaudio_compiled_apis[0])-1;
}

// 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 )
{
apis = std::vector<RtAudio::Api>(rtaudio_compiled_apis,
rtaudio_compiled_apis + rtaudio_num_compiled_apis);
}

std::string RtAudio :: getApiName( RtAudio::Api api )
{
if (api < 0 || api >= RtAudio::NUM_APIS)
return "";
return rtaudio_api_names[api][0];
}

std::string RtAudio :: getApiDisplayName( RtAudio::Api api )
{
if (api < 0 || api >= RtAudio::NUM_APIS)
return "Unknown";
return rtaudio_api_names[api][1];
}

RtAudio::Api RtAudio :: getCompiledApiByName( const std::string &name )
{
unsigned int i=0;
for (i = 0; i < rtaudio_num_compiled_apis; ++i)
if (name == rtaudio_api_names[rtaudio_compiled_apis[i]][0])
return rtaudio_compiled_apis[i];
return RtAudio::UNSPECIFIED;
}

void RtAudio :: openRtApi( RtAudio::Api api )


+ 30
- 2
RtAudio.h View File

@@ -48,7 +48,11 @@
#define RTAUDIO_VERSION "5.0.0"

#if defined _WIN32 || defined __CYGWIN__
#define RTAUDIO_DLL_PUBLIC
#if defined(RTAUDIO_EXPORT)
#define RTAUDIO_DLL_PUBLIC __declspec(dllexport)
#else
#define RTAUDIO_DLL_PUBLIC
#endif
#else
#if __GNUC__ >= 4
#define RTAUDIO_DLL_PUBLIC __attribute__( (visibility( "default" )) )
@@ -285,7 +289,8 @@ class RTAUDIO_DLL_PUBLIC RtAudio
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. */
};

//! The public device information structure for returning queried values.
@@ -397,6 +402,29 @@ 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, this function will return the empty string.
*/
static std::string getApiName( 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, this function will return the empty string.
*/
static std::string getApiDisplayName( 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


+ 25
- 32
rtaudio_c.cpp View File

@@ -15,40 +15,33 @@ struct rtaudio {
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" const 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_api_name(rtaudio_api_t api) {
if (api < 0 || api >= RTAUDIO_API_NUM)
return NULL;
return rtaudio_api_names[api][0];
}

const char *rtaudio_api_display_name(rtaudio_api_t api)
{
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 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) {


+ 8
- 0
rtaudio_c.h View File

@@ -2,8 +2,12 @@
#define RTAUDIO_C_H

#if defined(RTAUDIO_EXPORT)
#if defined _WIN32 || defined __CYGWIN__
#define RTAUDIOAPI __declspec(dllexport)
#else
#define RTAUDIOAPI __attribute__((visibility("default")))
#endif
#else
#define RTAUDIOAPI //__declspec(dllimport)
#endif

@@ -64,6 +68,7 @@ typedef enum rtaudio_api {
RTAUDIO_API_WINDOWS_ASIO,
RTAUDIO_API_WINDOWS_DS,
RTAUDIO_API_DUMMY,
RTAUDIO_API_NUM,
} rtaudio_api_t;

#define NUM_SAMPLE_RATES 16
@@ -102,6 +107,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_api_name(rtaudio_api_t api);
RTAUDIOAPI const char *rtaudio_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);



+ 3
- 0
tests/CMakeLists.txt View 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 ${LIBRTAUDIO} ${LINKLIBS})

add_executable(testall testall.cpp)
target_link_libraries(testall ${LIBRTAUDIO} ${LINKLIBS})



+ 4
- 1
tests/Makefile.am View 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



+ 157
- 0
tests/apinames.cpp View File

@@ -0,0 +1,157 @@
/******************************************/
/*
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 test_cpp() {
std::vector<RtAudio::Api> apis;
RtAudio::getCompiledApi( apis );

// ensure the known APIs return valid names
std::cout << "API names by identifier (C++):\n";
for ( size_t i = 0; i < apis.size() ; ++i ) {
const std::string name = RtAudio::getApiName(apis[i]);
if (name.empty()) {
std::cout << "Invalid name for API " << (int)apis[i] << "\n";
exit(1);
}
const std::string displayName = RtAudio::getApiDisplayName(apis[i]);
if (displayName.empty()) {
std::cout << "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::getApiName((RtAudio::Api)-1);
if (!name.empty()) {
std::cout << "Bad string for invalid API '" << name << "'\n";
exit(1);
}
const std::string displayName = RtAudio::getApiDisplayName((RtAudio::Api)-1);
if (displayName!="Unknown") {
std::cout << "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; i < apis.size() ; ++i ) {
std::string name = RtAudio::getApiName(apis[i]);
if ( RtAudio::getCompiledApiByName(name) != apis[i] ) {
std::cout << "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::cout << "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::cout << "Bad identifier for unknown API name\n";
exit( 1 );
}
}

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_api_name(apis[i]);
if (name.empty()) {
std::cout << "Invalid name for API " << (int)apis[i] << "\n";
exit(1);
}
const std::string displayName = rtaudio_api_display_name(apis[i]);
if (displayName.empty()) {
std::cout << "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_api_name((rtaudio_api_t)-1);
const std::string name(s?s:"");
if (!name.empty()) {
std::cout << "Bad string for invalid API '" << name << "'\n";
exit(1);
}
s = rtaudio_api_display_name((rtaudio_api_t)-1);
const std::string displayName(s?s:"");
if (displayName!="Unknown") {
std::cout << "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_api_name(apis[i]);
std::string name(s?s:"");
if ( rtaudio_compiled_api_by_name(name.c_str()) != apis[i] ) {
std::cout << "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::cout << "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::cout << "Bad identifier for unknown API name\n";
exit( 1 );
}
}

return 0;
}

int main()
{
test_cpp();
test_c();
}

Loading…
Cancel
Save