emulators/{citra,yuzu}: enable SNDIO by default
To avoid runtime dependency switch to dlopen(3).
This commit is contained in:
parent
fa90bbcc7a
commit
a7edc2d836
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=511424
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PORTREVISION= 0
|
||||
PORTREVISION= 1
|
||||
PKGNAMESUFFIX= -qt5
|
||||
|
||||
MASTERDIR= ${.CURDIR}/../citra
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
PORTNAME= citra
|
||||
PORTVERSION= s20190906
|
||||
PORTREVISION?= 0
|
||||
PORTREVISION?= 1
|
||||
CATEGORIES= emulators
|
||||
|
||||
MAINTAINER= jbeich@FreeBSD.org
|
||||
@ -45,13 +45,13 @@ LDFLAGS+= -Wl,--as-needed # Qt5Network
|
||||
TEST_TARGET= test
|
||||
|
||||
OPTIONS_DEFINE= ALSA FFMPEG PULSEAUDIO JACK SNDIO
|
||||
OPTIONS_DEFAULT=ALSA FFMPEG PULSEAUDIO JACK
|
||||
OPTIONS_DEFAULT=ALSA FFMPEG PULSEAUDIO JACK SNDIO
|
||||
OPTIONS_MULTI= GUI
|
||||
OPTIONS_MULTI_GUI= QT5 SDL
|
||||
OPTIONS_SLAVE?= SDL
|
||||
OPTIONS_EXCLUDE:= ${OPTIONS_MULTI_GUI}
|
||||
|
||||
ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib
|
||||
ALSA_BUILD_DEPENDS= alsa-lib>0:audio/alsa-lib
|
||||
ALSA_RUN_DEPENDS= ${LOCALBASE}/lib/alsa-lib/libasound_module_pcm_oss.so:audio/alsa-plugins
|
||||
ALSA_CMAKE_BOOL= USE_ALSA
|
||||
|
||||
@ -64,7 +64,7 @@ JACK_CMAKE_BOOL= USE_JACK
|
||||
PULSEAUDIO_BUILD_DEPENDS=pulseaudio>0.:audio/pulseaudio
|
||||
PULSEAUDIO_CMAKE_BOOL= USE_PULSE
|
||||
|
||||
SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio
|
||||
SNDIO_BUILD_DEPENDS= sndio>0:audio/sndio
|
||||
SNDIO_CMAKE_BOOL= USE_SNDIO
|
||||
|
||||
SDL_CMAKE_BOOL= ENABLE_SDL2
|
||||
|
809
emulators/citra/files/patch-cubeb-dlopen
Normal file
809
emulators/citra/files/patch-cubeb-dlopen
Normal file
@ -0,0 +1,809 @@
|
||||
https://github.com/kinetiknz/cubeb/commit/0d1d9d84fb3e
|
||||
https://github.com/kinetiknz/cubeb/pull/539
|
||||
|
||||
diff --git externals/cubeb/CMakeLists.txt externals/cubeb/CMakeLists.txt
|
||||
index cdb00f9..71373cb 100644
|
||||
--- externals/cubeb/CMakeLists.txt
|
||||
+++ externals/cubeb/CMakeLists.txt
|
||||
@@ -135,10 +135,7 @@ if(USE_PULSE)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_pulse.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_PULSE)
|
||||
- target_link_libraries(cubeb PRIVATE pulse)
|
||||
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
- target_link_libraries(cubeb PRIVATE dl)
|
||||
- endif()
|
||||
+ target_link_libraries(cubeb PRIVATE pthread ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
check_include_files(alsa/asoundlib.h USE_ALSA)
|
||||
@@ -146,10 +143,7 @@ if(USE_ALSA)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_alsa.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_ALSA)
|
||||
- target_link_libraries(cubeb PRIVATE asound pthread)
|
||||
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
- target_link_libraries(cubeb PRIVATE dl)
|
||||
- endif()
|
||||
+ target_link_libraries(cubeb PRIVATE pthread ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
check_include_files(jack/jack.h USE_JACK)
|
||||
@@ -157,10 +151,7 @@ if(USE_JACK)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_jack.cpp)
|
||||
target_compile_definitions(cubeb PRIVATE USE_JACK)
|
||||
- target_link_libraries(cubeb PRIVATE jack pthread)
|
||||
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
- target_link_libraries(cubeb PRIVATE dl)
|
||||
- endif()
|
||||
+ target_link_libraries(cubeb PRIVATE pthread ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
check_include_files(audioclient.h USE_WASAPI)
|
||||
@@ -201,7 +192,7 @@ if(USE_SNDIO)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_sndio.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_SNDIO)
|
||||
- target_link_libraries(cubeb PRIVATE sndio)
|
||||
+ target_link_libraries(cubeb PRIVATE pthread)
|
||||
endif()
|
||||
|
||||
check_include_files(kai.h USE_KAI)
|
||||
diff --git externals/cubeb/src/cubeb.c externals/cubeb/src/cubeb.c
|
||||
index e562a35..d66dd16 100644
|
||||
--- externals/cubeb/src/cubeb.c
|
||||
+++ externals/cubeb/src/cubeb.c
|
||||
@@ -177,6 +177,9 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam
|
||||
#if defined(USE_JACK)
|
||||
jack_init,
|
||||
#endif
|
||||
+#if defined(USE_SNDIO)
|
||||
+ sndio_init,
|
||||
+#endif
|
||||
#if defined(USE_ALSA)
|
||||
alsa_init,
|
||||
#endif
|
||||
@@ -189,9 +192,6 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam
|
||||
#if defined(USE_WINMM)
|
||||
winmm_init,
|
||||
#endif
|
||||
-#if defined(USE_SNDIO)
|
||||
- sndio_init,
|
||||
-#endif
|
||||
#if defined(USE_OPENSL)
|
||||
opensl_init,
|
||||
#endif
|
||||
diff --git externals/cubeb/src/cubeb_alsa.c externals/cubeb/src/cubeb_alsa.c
|
||||
index bfd4d8f..a29eed0 100644
|
||||
--- externals/cubeb/src/cubeb_alsa.c
|
||||
+++ externals/cubeb/src/cubeb_alsa.c
|
||||
@@ -14,10 +14,58 @@
|
||||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
+#include <dlfcn.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
|
||||
+#ifdef DISABLE_LIBASOUND_DLOPEN
|
||||
+#define WRAP(x) x
|
||||
+#else
|
||||
+#define WRAP(x) cubeb_##x
|
||||
+#define LIBASOUND_API_VISIT(X) \
|
||||
+ X(snd_config) \
|
||||
+ X(snd_config_add) \
|
||||
+ X(snd_config_copy) \
|
||||
+ X(snd_config_delete) \
|
||||
+ X(snd_config_get_id) \
|
||||
+ X(snd_config_get_string) \
|
||||
+ X(snd_config_imake_integer) \
|
||||
+ X(snd_config_search) \
|
||||
+ X(snd_config_search_definition) \
|
||||
+ X(snd_lib_error_set_handler) \
|
||||
+ X(snd_pcm_avail_update) \
|
||||
+ X(snd_pcm_close) \
|
||||
+ X(snd_pcm_delay) \
|
||||
+ X(snd_pcm_drain) \
|
||||
+ X(snd_pcm_frames_to_bytes) \
|
||||
+ X(snd_pcm_get_params) \
|
||||
+ X(snd_pcm_hw_params_any) \
|
||||
+ X(snd_pcm_hw_params_get_channels_max) \
|
||||
+ X(snd_pcm_hw_params_get_rate) \
|
||||
+ X(snd_pcm_hw_params_set_rate_near) \
|
||||
+ X(snd_pcm_hw_params_sizeof) \
|
||||
+ X(snd_pcm_nonblock) \
|
||||
+ X(snd_pcm_open) \
|
||||
+ X(snd_pcm_open_lconf) \
|
||||
+ X(snd_pcm_pause) \
|
||||
+ X(snd_pcm_poll_descriptors) \
|
||||
+ X(snd_pcm_poll_descriptors_count) \
|
||||
+ X(snd_pcm_poll_descriptors_revents) \
|
||||
+ X(snd_pcm_readi) \
|
||||
+ X(snd_pcm_recover) \
|
||||
+ X(snd_pcm_set_params) \
|
||||
+ X(snd_pcm_start) \
|
||||
+ X(snd_pcm_state) \
|
||||
+ X(snd_pcm_writei) \
|
||||
+
|
||||
+#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
|
||||
+LIBASOUND_API_VISIT(MAKE_TYPEDEF);
|
||||
+#undef MAKE_TYPEDEF
|
||||
+/* snd_pcm_hw_params_alloca is actually a macro */
|
||||
+#define snd_pcm_hw_params_sizeof cubeb_snd_pcm_hw_params_sizeof
|
||||
+#endif
|
||||
+
|
||||
#define CUBEB_STREAM_MAX 16
|
||||
#define CUBEB_WATCHDOG_MS 10000
|
||||
|
||||
@@ -36,6 +84,7 @@ static struct cubeb_ops const alsa_ops;
|
||||
|
||||
struct cubeb {
|
||||
struct cubeb_ops const * ops;
|
||||
+ void * libasound;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
@@ -245,8 +294,8 @@ set_timeout(struct timeval * timeout, unsigned int ms)
|
||||
static void
|
||||
stream_buffer_decrement(cubeb_stream * stm, long count)
|
||||
{
|
||||
- char * bufremains = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, count);
|
||||
- memmove(stm->buffer, bufremains, snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes - count));
|
||||
+ char * bufremains = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, count);
|
||||
+ memmove(stm->buffer, bufremains, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes - count));
|
||||
stm->bufframes -= count;
|
||||
}
|
||||
|
||||
@@ -278,9 +327,9 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
/* Call _poll_descriptors_revents() even if we don't use it
|
||||
to let underlying plugins clear null events. Otherwise poll()
|
||||
may wake up again and again, producing unnecessary CPU usage. */
|
||||
- snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents);
|
||||
+ WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents);
|
||||
|
||||
- avail = snd_pcm_avail_update(stm->pcm);
|
||||
+ avail = WRAP(snd_pcm_avail_update)(stm->pcm);
|
||||
|
||||
/* Got null event? Bail and wait for another wakeup. */
|
||||
if (avail == 0) {
|
||||
@@ -303,7 +352,7 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
// TODO: should it be marked as DRAINING?
|
||||
}
|
||||
|
||||
- got = snd_pcm_readi(stm->pcm, stm->buffer+stm->bufframes, avail);
|
||||
+ got = WRAP(snd_pcm_readi)(stm->pcm, stm->buffer+stm->bufframes, avail);
|
||||
|
||||
if (got < 0) {
|
||||
avail = got; // the error handler below will recover us
|
||||
@@ -347,7 +396,7 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
(!stm->other_stream || stm->other_stream->bufframes > 0)) {
|
||||
long got = avail - stm->bufframes;
|
||||
void * other_buffer = stm->other_stream ? stm->other_stream->buffer : NULL;
|
||||
- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes);
|
||||
+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes);
|
||||
|
||||
/* Correct read size to the other stream available frames */
|
||||
if (stm->other_stream && got > (snd_pcm_sframes_t) stm->other_stream->bufframes) {
|
||||
@@ -374,8 +423,8 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
long drain_frames = avail - stm->bufframes;
|
||||
double drain_time = (double) drain_frames / stm->params.rate;
|
||||
|
||||
- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes);
|
||||
- memset(buftail, 0, snd_pcm_frames_to_bytes(stm->pcm, drain_frames));
|
||||
+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes);
|
||||
+ memset(buftail, 0, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, drain_frames));
|
||||
stm->bufframes = avail;
|
||||
|
||||
/* Mark as draining, unless we're waiting for capture */
|
||||
@@ -402,7 +451,7 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
}
|
||||
}
|
||||
|
||||
- wrote = snd_pcm_writei(stm->pcm, stm->buffer, avail);
|
||||
+ wrote = WRAP(snd_pcm_writei)(stm->pcm, stm->buffer, avail);
|
||||
if (wrote < 0) {
|
||||
avail = wrote; // the error handler below will recover us
|
||||
} else {
|
||||
@@ -415,13 +464,13 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
|
||||
/* Got some error? Let's try to recover the stream. */
|
||||
if (avail < 0) {
|
||||
- avail = snd_pcm_recover(stm->pcm, avail, 0);
|
||||
+ avail = WRAP(snd_pcm_recover)(stm->pcm, avail, 0);
|
||||
|
||||
/* Capture pcm must be started after initial setup/recover */
|
||||
if (avail >= 0 &&
|
||||
stm->stream_type == SND_PCM_STREAM_CAPTURE &&
|
||||
- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
- avail = snd_pcm_start(stm->pcm);
|
||||
+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
+ avail = WRAP(snd_pcm_start)(stm->pcm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,26 +586,26 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
|
||||
|
||||
slave_def = NULL;
|
||||
|
||||
- r = snd_config_search(root_pcm, "slave", &slave_pcm);
|
||||
+ r = WRAP(snd_config_search)(root_pcm, "slave", &slave_pcm);
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- r = snd_config_get_string(slave_pcm, &string);
|
||||
+ r = WRAP(snd_config_get_string)(slave_pcm, &string);
|
||||
if (r >= 0) {
|
||||
- r = snd_config_search_definition(lconf, "pcm_slave", string, &slave_def);
|
||||
+ r = WRAP(snd_config_search_definition)(lconf, "pcm_slave", string, &slave_def);
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
- r = snd_config_search(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
|
||||
+ r = WRAP(snd_config_search)(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_get_string(slave_def ? slave_def : slave_pcm, &string);
|
||||
+ r = WRAP(snd_config_get_string)(slave_def ? slave_def : slave_pcm, &string);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -565,7 +614,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
|
||||
if (r < 0 || r > (int) sizeof(node_name)) {
|
||||
break;
|
||||
}
|
||||
- r = snd_config_search(lconf, node_name, &pcm);
|
||||
+ r = WRAP(snd_config_search)(lconf, node_name, &pcm);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -574,7 +623,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
|
||||
} while (0);
|
||||
|
||||
if (slave_def) {
|
||||
- snd_config_delete(slave_def);
|
||||
+ WRAP(snd_config_delete)(slave_def);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -597,22 +646,22 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
|
||||
lconf = NULL;
|
||||
|
||||
- if (snd_config == NULL) {
|
||||
+ if (*WRAP(snd_config) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- r = snd_config_copy(&lconf, snd_config);
|
||||
+ r = WRAP(snd_config_copy)(&lconf, *WRAP(snd_config));
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
- r = snd_config_search_definition(lconf, "pcm", pcm_name, &pcm_node);
|
||||
+ r = WRAP(snd_config_search_definition)(lconf, "pcm", pcm_name, &pcm_node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_get_id(pcm_node, &string);
|
||||
+ r = WRAP(snd_config_get_id)(pcm_node, &string);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -621,7 +670,7 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
if (r < 0 || r > (int) sizeof(node_name)) {
|
||||
break;
|
||||
}
|
||||
- r = snd_config_search(lconf, node_name, &pcm_node);
|
||||
+ r = WRAP(snd_config_search)(lconf, node_name, &pcm_node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -632,12 +681,12 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
}
|
||||
|
||||
/* Fetch the PCM node's type, and bail out if it's not the PulseAudio plugin. */
|
||||
- r = snd_config_search(pcm_node, "type", &node);
|
||||
+ r = WRAP(snd_config_search)(pcm_node, "type", &node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_get_string(node, &string);
|
||||
+ r = WRAP(snd_config_get_string)(node, &string);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -648,18 +697,18 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
|
||||
/* Don't clobber an explicit existing handle_underrun value, set it only
|
||||
if it doesn't already exist. */
|
||||
- r = snd_config_search(pcm_node, "handle_underrun", &node);
|
||||
+ r = WRAP(snd_config_search)(pcm_node, "handle_underrun", &node);
|
||||
if (r != -ENOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable pcm_pulse's asynchronous underrun handling. */
|
||||
- r = snd_config_imake_integer(&node, "handle_underrun", 0);
|
||||
+ r = WRAP(snd_config_imake_integer)(&node, "handle_underrun", 0);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_add(pcm_node, node);
|
||||
+ r = WRAP(snd_config_add)(pcm_node, node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -667,7 +716,7 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
return lconf;
|
||||
} while (0);
|
||||
|
||||
- snd_config_delete(lconf);
|
||||
+ WRAP(snd_config_delete)(lconf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -679,9 +728,9 @@ alsa_locked_pcm_open(snd_pcm_t ** pcm, char const * pcm_name, snd_pcm_stream_t s
|
||||
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
if (local_config) {
|
||||
- r = snd_pcm_open_lconf(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config);
|
||||
+ r = WRAP(snd_pcm_open_lconf)(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config);
|
||||
} else {
|
||||
- r = snd_pcm_open(pcm, pcm_name, stream, SND_PCM_NONBLOCK);
|
||||
+ r = WRAP(snd_pcm_open)(pcm, pcm_name, stream, SND_PCM_NONBLOCK);
|
||||
}
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
|
||||
@@ -694,7 +743,7 @@ alsa_locked_pcm_close(snd_pcm_t * pcm)
|
||||
int r;
|
||||
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
- r = snd_pcm_close(pcm);
|
||||
+ r = WRAP(snd_pcm_close)(pcm);
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
|
||||
return r;
|
||||
@@ -750,6 +799,7 @@ silent_error_handler(char const * file, int line, char const * function,
|
||||
alsa_init(cubeb ** context, char const * context_name)
|
||||
{
|
||||
(void)context_name;
|
||||
+ void * libasound = NULL;
|
||||
cubeb * ctx;
|
||||
int r;
|
||||
int i;
|
||||
@@ -760,9 +810,27 @@ alsa_init(cubeb ** context, char const * context_name)
|
||||
assert(context);
|
||||
*context = NULL;
|
||||
|
||||
+#ifndef DISABLE_LIBASOUND_DLOPEN
|
||||
+ libasound = dlopen("libasound.so", RTLD_LAZY);
|
||||
+ if (!libasound) {
|
||||
+ return CUBEB_ERROR;
|
||||
+ }
|
||||
+
|
||||
+#define LOAD(x) { \
|
||||
+ cubeb_##x = dlsym(libasound, #x); \
|
||||
+ if (!cubeb_##x) { \
|
||||
+ dlclose(libasound); \
|
||||
+ return CUBEB_ERROR; \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+ LIBASOUND_API_VISIT(LOAD);
|
||||
+#undef LOAD
|
||||
+#endif
|
||||
+
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
if (!cubeb_alsa_error_handler_set) {
|
||||
- snd_lib_error_set_handler(silent_error_handler);
|
||||
+ WRAP(snd_lib_error_set_handler)(silent_error_handler);
|
||||
cubeb_alsa_error_handler_set = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
@@ -771,6 +839,7 @@ alsa_init(cubeb ** context, char const * context_name)
|
||||
assert(ctx);
|
||||
|
||||
ctx->ops = &alsa_ops;
|
||||
+ ctx->libasound = libasound;
|
||||
|
||||
r = pthread_mutex_init(&ctx->mutex, NULL);
|
||||
assert(r == 0);
|
||||
@@ -819,7 +888,7 @@ alsa_init(cubeb ** context, char const * context_name)
|
||||
config fails with EINVAL, the PA PCM is too old for this workaround. */
|
||||
if (r == -EINVAL) {
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
- snd_config_delete(ctx->local_config);
|
||||
+ WRAP(snd_config_delete)(ctx->local_config);
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
ctx->local_config = NULL;
|
||||
} else if (r >= 0) {
|
||||
@@ -861,10 +930,14 @@ alsa_destroy(cubeb * ctx)
|
||||
|
||||
if (ctx->local_config) {
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
- snd_config_delete(ctx->local_config);
|
||||
+ WRAP(snd_config_delete)(ctx->local_config);
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
}
|
||||
|
||||
+ if (ctx->libasound) {
|
||||
+ dlclose(ctx->libasound);
|
||||
+ }
|
||||
+
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
@@ -948,7 +1021,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_nonblock(stm->pcm, 1);
|
||||
+ r = WRAP(snd_pcm_nonblock)(stm->pcm, 1);
|
||||
assert(r == 0);
|
||||
|
||||
latency_us = latency_frames * 1e6 / stm->params.rate;
|
||||
@@ -961,7 +1034,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream
|
||||
latency_us = latency_us < min_latency ? min_latency: latency_us;
|
||||
}
|
||||
|
||||
- r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
+ r = WRAP(snd_pcm_set_params)(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
stm->params.channels, stm->params.rate, 1,
|
||||
latency_us);
|
||||
if (r < 0) {
|
||||
@@ -969,20 +1042,20 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream
|
||||
return CUBEB_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
- r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &period_size);
|
||||
+ r = WRAP(snd_pcm_get_params)(stm->pcm, &stm->buffer_size, &period_size);
|
||||
assert(r == 0);
|
||||
|
||||
/* Double internal buffer size to have enough space when waiting for the other side of duplex connection */
|
||||
stm->buffer_size *= 2;
|
||||
- stm->buffer = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, stm->buffer_size));
|
||||
+ stm->buffer = calloc(1, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->buffer_size));
|
||||
assert(stm->buffer);
|
||||
|
||||
- stm->nfds = snd_pcm_poll_descriptors_count(stm->pcm);
|
||||
+ stm->nfds = WRAP(snd_pcm_poll_descriptors_count)(stm->pcm);
|
||||
assert(stm->nfds > 0);
|
||||
|
||||
stm->saved_fds = calloc(stm->nfds, sizeof(struct pollfd));
|
||||
assert(stm->saved_fds);
|
||||
- r = snd_pcm_poll_descriptors(stm->pcm, stm->saved_fds, stm->nfds);
|
||||
+ r = WRAP(snd_pcm_poll_descriptors)(stm->pcm, stm->saved_fds, stm->nfds);
|
||||
assert((nfds_t) r == stm->nfds);
|
||||
|
||||
if (alsa_register_stream(ctx, stm) != 0) {
|
||||
@@ -1054,7 +1127,7 @@ alsa_stream_destroy(cubeb_stream * stm)
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
if (stm->pcm) {
|
||||
if (stm->state == DRAINING) {
|
||||
- snd_pcm_drain(stm->pcm);
|
||||
+ WRAP(snd_pcm_drain)(stm->pcm);
|
||||
}
|
||||
alsa_locked_pcm_close(stm->pcm);
|
||||
stm->pcm = NULL;
|
||||
@@ -1100,12 +1173,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
|
||||
assert(stm);
|
||||
|
||||
- r = snd_pcm_hw_params_any(stm->pcm, hw_params);
|
||||
+ r = WRAP(snd_pcm_hw_params_any)(stm->pcm, hw_params);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_hw_params_get_channels_max(hw_params, max_channels);
|
||||
+ r = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
@@ -1126,34 +1199,34 @@ alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) {
|
||||
|
||||
/* get a pcm, disabling resampling, so we get a rate the
|
||||
* hardware/dmix/pulse/etc. supports. */
|
||||
- r = snd_pcm_open(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE);
|
||||
+ r = WRAP(snd_pcm_open)(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_hw_params_any(pcm, hw_params);
|
||||
+ r = WRAP(snd_pcm_hw_params_any)(pcm, hw_params);
|
||||
if (r < 0) {
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir);
|
||||
+ r = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &dir);
|
||||
if (r >= 0) {
|
||||
/* There is a default rate: use it. */
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
/* Use a common rate, alsa may adjust it based on hw/etc. capabilities. */
|
||||
*rate = 44100;
|
||||
|
||||
- r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL);
|
||||
+ r = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL);
|
||||
if (r < 0) {
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
@@ -1186,10 +1259,10 @@ alsa_stream_start(cubeb_stream * stm)
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
/* Capture pcm must be started after initial setup/recover */
|
||||
if (stm->stream_type == SND_PCM_STREAM_CAPTURE &&
|
||||
- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
- snd_pcm_start(stm->pcm);
|
||||
+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
+ WRAP(snd_pcm_start)(stm->pcm);
|
||||
}
|
||||
- snd_pcm_pause(stm->pcm, 0);
|
||||
+ WRAP(snd_pcm_pause)(stm->pcm, 0);
|
||||
gettimeofday(&stm->last_activity, NULL);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
|
||||
@@ -1229,7 +1302,7 @@ alsa_stream_stop(cubeb_stream * stm)
|
||||
pthread_mutex_unlock(&ctx->mutex);
|
||||
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
- snd_pcm_pause(stm->pcm, 1);
|
||||
+ WRAP(snd_pcm_pause)(stm->pcm, 1);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
|
||||
return CUBEB_OK;
|
||||
@@ -1245,8 +1318,8 @@ alsa_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
|
||||
delay = -1;
|
||||
- if (snd_pcm_state(stm->pcm) != SND_PCM_STATE_RUNNING ||
|
||||
- snd_pcm_delay(stm->pcm, &delay) != 0) {
|
||||
+ if (WRAP(snd_pcm_state)(stm->pcm) != SND_PCM_STATE_RUNNING ||
|
||||
+ WRAP(snd_pcm_delay)(stm->pcm, &delay) != 0) {
|
||||
*position = stm->last_position;
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
return CUBEB_OK;
|
||||
@@ -1271,7 +1344,7 @@ alsa_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
|
||||
snd_pcm_sframes_t delay;
|
||||
/* This function returns the delay in frames until a frame written using
|
||||
snd_pcm_writei is sent to the DAC. The DAC delay should be < 1ms anyways. */
|
||||
- if (snd_pcm_delay(stm->pcm, &delay)) {
|
||||
+ if (WRAP(snd_pcm_delay)(stm->pcm, &delay)) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
diff --git externals/cubeb/src/cubeb_sndio.c externals/cubeb/src/cubeb_sndio.c
|
||||
index 5a43343..c9a31a7 100644
|
||||
--- externals/cubeb/src/cubeb_sndio.c
|
||||
+++ externals/cubeb/src/cubeb_sndio.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
+#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
@@ -22,10 +23,36 @@
|
||||
#define DPR(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
+#ifdef DISABLE_LIBSNDIO_DLOPEN
|
||||
+#define WRAP(x) x
|
||||
+#else
|
||||
+#define WRAP(x) cubeb_##x
|
||||
+#define LIBSNDIO_API_VISIT(X) \
|
||||
+ X(sio_close) \
|
||||
+ X(sio_eof) \
|
||||
+ X(sio_getpar) \
|
||||
+ X(sio_initpar) \
|
||||
+ X(sio_onmove) \
|
||||
+ X(sio_open) \
|
||||
+ X(sio_pollfd) \
|
||||
+ X(sio_read) \
|
||||
+ X(sio_revents) \
|
||||
+ X(sio_setpar) \
|
||||
+ X(sio_setvol) \
|
||||
+ X(sio_start) \
|
||||
+ X(sio_stop) \
|
||||
+ X(sio_write) \
|
||||
+
|
||||
+#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
|
||||
+LIBSNDIO_API_VISIT(MAKE_TYPEDEF);
|
||||
+#undef MAKE_TYPEDEF
|
||||
+#endif
|
||||
+
|
||||
static struct cubeb_ops const sndio_ops;
|
||||
|
||||
struct cubeb {
|
||||
struct cubeb_ops const * ops;
|
||||
+ void * libsndio;
|
||||
};
|
||||
|
||||
struct cubeb_stream {
|
||||
@@ -103,7 +130,7 @@ sndio_mainloop(void *arg)
|
||||
DPR("sndio_mainloop()\n");
|
||||
s->state_cb(s, s->arg, CUBEB_STATE_STARTED);
|
||||
pthread_mutex_lock(&s->mtx);
|
||||
- if (!sio_start(s->hdl)) {
|
||||
+ if (!WRAP(sio_start)(s->hdl)) {
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
return NULL;
|
||||
}
|
||||
@@ -183,7 +210,7 @@ sndio_mainloop(void *arg)
|
||||
events |= POLLIN;
|
||||
if ((s->mode & SIO_PLAY) && pstart < pend)
|
||||
events |= POLLOUT;
|
||||
- nfds = sio_pollfd(s->hdl, pfds, events);
|
||||
+ nfds = WRAP(sio_pollfd)(s->hdl, pfds, events);
|
||||
|
||||
if (nfds > 0) {
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
@@ -193,7 +220,7 @@ sndio_mainloop(void *arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
- revents = sio_revents(s->hdl, pfds);
|
||||
+ revents = WRAP(sio_revents)(s->hdl, pfds);
|
||||
|
||||
if (revents & POLLHUP) {
|
||||
state = CUBEB_STATE_ERROR;
|
||||
@@ -201,8 +228,8 @@ sndio_mainloop(void *arg)
|
||||
}
|
||||
|
||||
if (revents & POLLOUT) {
|
||||
- n = sio_write(s->hdl, s->pbuf + pstart, pend - pstart);
|
||||
- if (n == 0 && sio_eof(s->hdl)) {
|
||||
+ n = WRAP(sio_write)(s->hdl, s->pbuf + pstart, pend - pstart);
|
||||
+ if (n == 0 && WRAP(sio_eof)(s->hdl)) {
|
||||
DPR("sndio_mainloop() werr\n");
|
||||
state = CUBEB_STATE_ERROR;
|
||||
break;
|
||||
@@ -211,8 +238,8 @@ sndio_mainloop(void *arg)
|
||||
}
|
||||
|
||||
if (revents & POLLIN) {
|
||||
- n = sio_read(s->hdl, s->rbuf + rstart, rend - rstart);
|
||||
- if (n == 0 && sio_eof(s->hdl)) {
|
||||
+ n = WRAP(sio_read)(s->hdl, s->rbuf + rstart, rend - rstart);
|
||||
+ if (n == 0 && WRAP(sio_eof)(s->hdl)) {
|
||||
DPR("sndio_mainloop() rerr\n");
|
||||
state = CUBEB_STATE_ERROR;
|
||||
break;
|
||||
@@ -224,7 +251,7 @@ sndio_mainloop(void *arg)
|
||||
if (prime > 0 && (s->mode & SIO_REC))
|
||||
rstart = rend;
|
||||
}
|
||||
- sio_stop(s->hdl);
|
||||
+ WRAP(sio_stop)(s->hdl);
|
||||
s->hwpos = s->swpos;
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
s->state_cb(s, s->arg, state);
|
||||
@@ -234,8 +261,31 @@ sndio_mainloop(void *arg)
|
||||
/*static*/ int
|
||||
sndio_init(cubeb **context, char const *context_name)
|
||||
{
|
||||
+ void * libsndio = NULL;
|
||||
+
|
||||
+#ifndef DISABLE_LIBSNDIO_DLOPEN
|
||||
+ libsndio = dlopen("libsndio.so", RTLD_LAZY);
|
||||
+ if (!libsndio) {
|
||||
+ DPR("sndio_init(%s) failed dlopen(libsndio.so)\n", context_name);
|
||||
+ return CUBEB_ERROR;
|
||||
+ }
|
||||
+
|
||||
+#define LOAD(x) { \
|
||||
+ cubeb_##x = dlsym(libsndio, #x); \
|
||||
+ if (!cubeb_##x) { \
|
||||
+ DPR("sndio_init(%s) failed dlsym(%s)\n", context_name, #x); \
|
||||
+ dlclose(libsndio); \
|
||||
+ return CUBEB_ERROR; \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+ LIBSNDIO_API_VISIT(LOAD);
|
||||
+#undef LOAD
|
||||
+#endif
|
||||
+
|
||||
DPR("sndio_init(%s)\n", context_name);
|
||||
*context = malloc(sizeof(*context));
|
||||
+ (*context)->libsndio = libsndio;
|
||||
(*context)->ops = &sndio_ops;
|
||||
(void)context_name;
|
||||
return CUBEB_OK;
|
||||
@@ -251,6 +301,8 @@ static void
|
||||
sndio_destroy(cubeb *context)
|
||||
{
|
||||
DPR("sndio_destroy()\n");
|
||||
+ if (context->libsndio)
|
||||
+ dlclose(context->libsndio);
|
||||
free(context);
|
||||
}
|
||||
|
||||
@@ -303,12 +355,12 @@ sndio_stream_init(cubeb * context,
|
||||
goto err;
|
||||
}
|
||||
s->context = context;
|
||||
- s->hdl = sio_open(NULL, s->mode, 1);
|
||||
+ s->hdl = WRAP(sio_open)(NULL, s->mode, 1);
|
||||
if (s->hdl == NULL) {
|
||||
DPR("sndio_stream_init(), sio_open() failed\n");
|
||||
goto err;
|
||||
}
|
||||
- sio_initpar(&wpar);
|
||||
+ WRAP(sio_initpar)(&wpar);
|
||||
wpar.sig = 1;
|
||||
wpar.bits = 16;
|
||||
switch (format) {
|
||||
@@ -331,7 +383,7 @@ sndio_stream_init(cubeb * context,
|
||||
if (s->mode & SIO_PLAY)
|
||||
wpar.pchan = output_stream_params->channels;
|
||||
wpar.appbufsz = latency_frames;
|
||||
- if (!sio_setpar(s->hdl, &wpar) || !sio_getpar(s->hdl, &rpar)) {
|
||||
+ if (!WRAP(sio_setpar)(s->hdl, &wpar) || !WRAP(sio_getpar)(s->hdl, &rpar)) {
|
||||
DPR("sndio_stream_init(), sio_setpar() failed\n");
|
||||
goto err;
|
||||
}
|
||||
@@ -342,7 +394,7 @@ sndio_stream_init(cubeb * context,
|
||||
DPR("sndio_stream_init() unsupported params\n");
|
||||
goto err;
|
||||
}
|
||||
- sio_onmove(s->hdl, sndio_onmove, s);
|
||||
+ WRAP(sio_onmove)(s->hdl, sndio_onmove, s);
|
||||
s->active = 0;
|
||||
s->nfr = rpar.round;
|
||||
s->rbpf = rpar.bps * rpar.rchan;
|
||||
@@ -379,7 +431,7 @@ sndio_stream_init(cubeb * context,
|
||||
return CUBEB_OK;
|
||||
err:
|
||||
if (s->hdl)
|
||||
- sio_close(s->hdl);
|
||||
+ WRAP(sio_close)(s->hdl);
|
||||
if (s->pbuf)
|
||||
free(s->pbuf);
|
||||
if (s->rbuf)
|
||||
@@ -425,7 +477,7 @@ static void
|
||||
sndio_stream_destroy(cubeb_stream *s)
|
||||
{
|
||||
DPR("sndio_stream_destroy()\n");
|
||||
- sio_close(s->hdl);
|
||||
+ WRAP(sio_close)(s->hdl);
|
||||
if (s->mode & SIO_PLAY)
|
||||
free(s->pbuf);
|
||||
if (s->mode & SIO_REC)
|
||||
@@ -476,7 +528,7 @@ sndio_stream_set_volume(cubeb_stream *s, float volume)
|
||||
{
|
||||
DPR("sndio_stream_set_volume(%f)\n", volume);
|
||||
pthread_mutex_lock(&s->mtx);
|
||||
- sio_setvol(s->hdl, SIO_MAXVOL * volume);
|
||||
+ WRAP(sio_setvol)(s->hdl, SIO_MAXVOL * volume);
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
return CUBEB_OK;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PORTREVISION= 0
|
||||
PORTREVISION= 1
|
||||
PKGNAMESUFFIX= -qt5
|
||||
|
||||
MASTERDIR= ${.CURDIR}/../yuzu
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
PORTNAME= yuzu
|
||||
PORTVERSION= s20190905
|
||||
PORTREVISION?= 0
|
||||
PORTREVISION?= 1
|
||||
CATEGORIES= emulators
|
||||
|
||||
MAINTAINER= jbeich@FreeBSD.org
|
||||
@ -53,13 +53,13 @@ LDFLAGS+= -Wl,--as-needed # Qt5Network
|
||||
TEST_TARGET= test
|
||||
|
||||
OPTIONS_DEFINE= ALSA PULSEAUDIO JACK SNDIO
|
||||
OPTIONS_DEFAULT=ALSA PULSEAUDIO JACK
|
||||
OPTIONS_DEFAULT=ALSA PULSEAUDIO JACK SNDIO
|
||||
OPTIONS_MULTI= GUI
|
||||
OPTIONS_MULTI_GUI= QT5 SDL
|
||||
OPTIONS_SLAVE?= SDL
|
||||
OPTIONS_EXCLUDE:= ${OPTIONS_MULTI_GUI}
|
||||
|
||||
ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib
|
||||
ALSA_BUILD_DEPENDS= alsa-lib>0:audio/alsa-lib
|
||||
ALSA_RUN_DEPENDS= ${LOCALBASE}/lib/alsa-lib/libasound_module_pcm_oss.so:audio/alsa-plugins
|
||||
ALSA_CMAKE_BOOL= USE_ALSA
|
||||
|
||||
@ -69,7 +69,7 @@ JACK_CMAKE_BOOL= USE_JACK
|
||||
PULSEAUDIO_BUILD_DEPENDS=pulseaudio>0.:audio/pulseaudio
|
||||
PULSEAUDIO_CMAKE_BOOL= USE_PULSE
|
||||
|
||||
SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio
|
||||
SNDIO_BUILD_DEPENDS= sndio>0:audio/sndio
|
||||
SNDIO_CMAKE_BOOL= USE_SNDIO
|
||||
|
||||
SDL_CMAKE_BOOL= ENABLE_SDL2
|
||||
|
799
emulators/yuzu/files/patch-cubeb-dlopen
Normal file
799
emulators/yuzu/files/patch-cubeb-dlopen
Normal file
@ -0,0 +1,799 @@
|
||||
https://github.com/kinetiknz/cubeb/commit/0d1d9d84fb3e
|
||||
https://github.com/kinetiknz/cubeb/pull/539
|
||||
|
||||
diff --git externals/cubeb/CMakeLists.txt externals/cubeb/CMakeLists.txt
|
||||
index cdb00f9..71373cb 100644
|
||||
--- externals/cubeb/CMakeLists.txt
|
||||
+++ externals/cubeb/CMakeLists.txt
|
||||
@@ -135,10 +135,7 @@ if(USE_PULSE)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_pulse.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_PULSE)
|
||||
- target_link_libraries(cubeb PRIVATE pulse)
|
||||
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
- target_link_libraries(cubeb PRIVATE dl)
|
||||
- endif()
|
||||
+ target_link_libraries(cubeb PRIVATE pthread ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
check_include_files(alsa/asoundlib.h USE_ALSA)
|
||||
@@ -146,10 +143,7 @@ if(USE_ALSA)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_alsa.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_ALSA)
|
||||
- target_link_libraries(cubeb PRIVATE asound pthread)
|
||||
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
- target_link_libraries(cubeb PRIVATE dl)
|
||||
- endif()
|
||||
+ target_link_libraries(cubeb PRIVATE pthread ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
check_include_files(jack/jack.h USE_JACK)
|
||||
@@ -157,10 +151,7 @@ if(USE_JACK)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_jack.cpp)
|
||||
target_compile_definitions(cubeb PRIVATE USE_JACK)
|
||||
- target_link_libraries(cubeb PRIVATE jack pthread)
|
||||
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
- target_link_libraries(cubeb PRIVATE dl)
|
||||
- endif()
|
||||
+ target_link_libraries(cubeb PRIVATE pthread ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
check_include_files(audioclient.h USE_WASAPI)
|
||||
@@ -201,7 +192,7 @@ if(USE_SNDIO)
|
||||
target_sources(cubeb PRIVATE
|
||||
src/cubeb_sndio.c)
|
||||
target_compile_definitions(cubeb PRIVATE USE_SNDIO)
|
||||
- target_link_libraries(cubeb PRIVATE sndio)
|
||||
+ target_link_libraries(cubeb PRIVATE pthread)
|
||||
endif()
|
||||
|
||||
check_include_files(kai.h USE_KAI)
|
||||
diff --git externals/cubeb/src/cubeb.c externals/cubeb/src/cubeb.c
|
||||
index e562a35..d66dd16 100644
|
||||
--- externals/cubeb/src/cubeb.c
|
||||
+++ externals/cubeb/src/cubeb.c
|
||||
@@ -177,6 +177,9 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam
|
||||
#if defined(USE_JACK)
|
||||
jack_init,
|
||||
#endif
|
||||
+#if defined(USE_SNDIO)
|
||||
+ sndio_init,
|
||||
+#endif
|
||||
#if defined(USE_ALSA)
|
||||
alsa_init,
|
||||
#endif
|
||||
@@ -189,9 +192,6 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam
|
||||
#if defined(USE_WINMM)
|
||||
winmm_init,
|
||||
#endif
|
||||
-#if defined(USE_SNDIO)
|
||||
- sndio_init,
|
||||
-#endif
|
||||
#if defined(USE_OPENSL)
|
||||
opensl_init,
|
||||
#endif
|
||||
diff --git externals/cubeb/src/cubeb_alsa.c externals/cubeb/src/cubeb_alsa.c
|
||||
index bfd4d8f..a29eed0 100644
|
||||
--- externals/cubeb/src/cubeb_alsa.c
|
||||
+++ externals/cubeb/src/cubeb_alsa.c
|
||||
@@ -14,10 +14,58 @@
|
||||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
+#include <dlfcn.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
|
||||
+#ifdef DISABLE_LIBASOUND_DLOPEN
|
||||
+#define WRAP(x) x
|
||||
+#else
|
||||
+#define WRAP(x) cubeb_##x
|
||||
+#define LIBASOUND_API_VISIT(X) \
|
||||
+ X(snd_config) \
|
||||
+ X(snd_config_add) \
|
||||
+ X(snd_config_copy) \
|
||||
+ X(snd_config_delete) \
|
||||
+ X(snd_config_get_id) \
|
||||
+ X(snd_config_get_string) \
|
||||
+ X(snd_config_imake_integer) \
|
||||
+ X(snd_config_search) \
|
||||
+ X(snd_config_search_definition) \
|
||||
+ X(snd_lib_error_set_handler) \
|
||||
+ X(snd_pcm_avail_update) \
|
||||
+ X(snd_pcm_close) \
|
||||
+ X(snd_pcm_delay) \
|
||||
+ X(snd_pcm_drain) \
|
||||
+ X(snd_pcm_frames_to_bytes) \
|
||||
+ X(snd_pcm_get_params) \
|
||||
+ X(snd_pcm_hw_params_any) \
|
||||
+ X(snd_pcm_hw_params_get_channels_max) \
|
||||
+ X(snd_pcm_hw_params_get_rate) \
|
||||
+ X(snd_pcm_hw_params_set_rate_near) \
|
||||
+ X(snd_pcm_hw_params_sizeof) \
|
||||
+ X(snd_pcm_nonblock) \
|
||||
+ X(snd_pcm_open) \
|
||||
+ X(snd_pcm_open_lconf) \
|
||||
+ X(snd_pcm_pause) \
|
||||
+ X(snd_pcm_poll_descriptors) \
|
||||
+ X(snd_pcm_poll_descriptors_count) \
|
||||
+ X(snd_pcm_poll_descriptors_revents) \
|
||||
+ X(snd_pcm_readi) \
|
||||
+ X(snd_pcm_recover) \
|
||||
+ X(snd_pcm_set_params) \
|
||||
+ X(snd_pcm_start) \
|
||||
+ X(snd_pcm_state) \
|
||||
+ X(snd_pcm_writei) \
|
||||
+
|
||||
+#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
|
||||
+LIBASOUND_API_VISIT(MAKE_TYPEDEF);
|
||||
+#undef MAKE_TYPEDEF
|
||||
+/* snd_pcm_hw_params_alloca is actually a macro */
|
||||
+#define snd_pcm_hw_params_sizeof cubeb_snd_pcm_hw_params_sizeof
|
||||
+#endif
|
||||
+
|
||||
#define CUBEB_STREAM_MAX 16
|
||||
#define CUBEB_WATCHDOG_MS 10000
|
||||
|
||||
@@ -36,6 +84,7 @@ static struct cubeb_ops const alsa_ops;
|
||||
|
||||
struct cubeb {
|
||||
struct cubeb_ops const * ops;
|
||||
+ void * libasound;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
@@ -245,8 +294,8 @@ set_timeout(struct timeval * timeout, unsigned int ms)
|
||||
static void
|
||||
stream_buffer_decrement(cubeb_stream * stm, long count)
|
||||
{
|
||||
- char * bufremains = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, count);
|
||||
- memmove(stm->buffer, bufremains, snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes - count));
|
||||
+ char * bufremains = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, count);
|
||||
+ memmove(stm->buffer, bufremains, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes - count));
|
||||
stm->bufframes -= count;
|
||||
}
|
||||
|
||||
@@ -278,9 +327,9 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
/* Call _poll_descriptors_revents() even if we don't use it
|
||||
to let underlying plugins clear null events. Otherwise poll()
|
||||
may wake up again and again, producing unnecessary CPU usage. */
|
||||
- snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents);
|
||||
+ WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents);
|
||||
|
||||
- avail = snd_pcm_avail_update(stm->pcm);
|
||||
+ avail = WRAP(snd_pcm_avail_update)(stm->pcm);
|
||||
|
||||
/* Got null event? Bail and wait for another wakeup. */
|
||||
if (avail == 0) {
|
||||
@@ -303,7 +352,7 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
// TODO: should it be marked as DRAINING?
|
||||
}
|
||||
|
||||
- got = snd_pcm_readi(stm->pcm, stm->buffer+stm->bufframes, avail);
|
||||
+ got = WRAP(snd_pcm_readi)(stm->pcm, stm->buffer+stm->bufframes, avail);
|
||||
|
||||
if (got < 0) {
|
||||
avail = got; // the error handler below will recover us
|
||||
@@ -347,7 +396,7 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
(!stm->other_stream || stm->other_stream->bufframes > 0)) {
|
||||
long got = avail - stm->bufframes;
|
||||
void * other_buffer = stm->other_stream ? stm->other_stream->buffer : NULL;
|
||||
- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes);
|
||||
+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes);
|
||||
|
||||
/* Correct read size to the other stream available frames */
|
||||
if (stm->other_stream && got > (snd_pcm_sframes_t) stm->other_stream->bufframes) {
|
||||
@@ -374,8 +423,8 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
long drain_frames = avail - stm->bufframes;
|
||||
double drain_time = (double) drain_frames / stm->params.rate;
|
||||
|
||||
- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes);
|
||||
- memset(buftail, 0, snd_pcm_frames_to_bytes(stm->pcm, drain_frames));
|
||||
+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes);
|
||||
+ memset(buftail, 0, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, drain_frames));
|
||||
stm->bufframes = avail;
|
||||
|
||||
/* Mark as draining, unless we're waiting for capture */
|
||||
@@ -402,7 +451,7 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
}
|
||||
}
|
||||
|
||||
- wrote = snd_pcm_writei(stm->pcm, stm->buffer, avail);
|
||||
+ wrote = WRAP(snd_pcm_writei)(stm->pcm, stm->buffer, avail);
|
||||
if (wrote < 0) {
|
||||
avail = wrote; // the error handler below will recover us
|
||||
} else {
|
||||
@@ -415,13 +464,13 @@ alsa_process_stream(cubeb_stream * stm)
|
||||
|
||||
/* Got some error? Let's try to recover the stream. */
|
||||
if (avail < 0) {
|
||||
- avail = snd_pcm_recover(stm->pcm, avail, 0);
|
||||
+ avail = WRAP(snd_pcm_recover)(stm->pcm, avail, 0);
|
||||
|
||||
/* Capture pcm must be started after initial setup/recover */
|
||||
if (avail >= 0 &&
|
||||
stm->stream_type == SND_PCM_STREAM_CAPTURE &&
|
||||
- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
- avail = snd_pcm_start(stm->pcm);
|
||||
+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
+ avail = WRAP(snd_pcm_start)(stm->pcm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,26 +586,26 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
|
||||
|
||||
slave_def = NULL;
|
||||
|
||||
- r = snd_config_search(root_pcm, "slave", &slave_pcm);
|
||||
+ r = WRAP(snd_config_search)(root_pcm, "slave", &slave_pcm);
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- r = snd_config_get_string(slave_pcm, &string);
|
||||
+ r = WRAP(snd_config_get_string)(slave_pcm, &string);
|
||||
if (r >= 0) {
|
||||
- r = snd_config_search_definition(lconf, "pcm_slave", string, &slave_def);
|
||||
+ r = WRAP(snd_config_search_definition)(lconf, "pcm_slave", string, &slave_def);
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
- r = snd_config_search(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
|
||||
+ r = WRAP(snd_config_search)(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_get_string(slave_def ? slave_def : slave_pcm, &string);
|
||||
+ r = WRAP(snd_config_get_string)(slave_def ? slave_def : slave_pcm, &string);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -565,7 +614,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
|
||||
if (r < 0 || r > (int) sizeof(node_name)) {
|
||||
break;
|
||||
}
|
||||
- r = snd_config_search(lconf, node_name, &pcm);
|
||||
+ r = WRAP(snd_config_search)(lconf, node_name, &pcm);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -574,7 +623,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
|
||||
} while (0);
|
||||
|
||||
if (slave_def) {
|
||||
- snd_config_delete(slave_def);
|
||||
+ WRAP(snd_config_delete)(slave_def);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -597,22 +646,22 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
|
||||
lconf = NULL;
|
||||
|
||||
- if (snd_config == NULL) {
|
||||
+ if (*WRAP(snd_config) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- r = snd_config_copy(&lconf, snd_config);
|
||||
+ r = WRAP(snd_config_copy)(&lconf, *WRAP(snd_config));
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
- r = snd_config_search_definition(lconf, "pcm", pcm_name, &pcm_node);
|
||||
+ r = WRAP(snd_config_search_definition)(lconf, "pcm", pcm_name, &pcm_node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_get_id(pcm_node, &string);
|
||||
+ r = WRAP(snd_config_get_id)(pcm_node, &string);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -621,7 +670,7 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
if (r < 0 || r > (int) sizeof(node_name)) {
|
||||
break;
|
||||
}
|
||||
- r = snd_config_search(lconf, node_name, &pcm_node);
|
||||
+ r = WRAP(snd_config_search)(lconf, node_name, &pcm_node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -632,12 +681,12 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
}
|
||||
|
||||
/* Fetch the PCM node's type, and bail out if it's not the PulseAudio plugin. */
|
||||
- r = snd_config_search(pcm_node, "type", &node);
|
||||
+ r = WRAP(snd_config_search)(pcm_node, "type", &node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_get_string(node, &string);
|
||||
+ r = WRAP(snd_config_get_string)(node, &string);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -648,18 +697,18 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
|
||||
/* Don't clobber an explicit existing handle_underrun value, set it only
|
||||
if it doesn't already exist. */
|
||||
- r = snd_config_search(pcm_node, "handle_underrun", &node);
|
||||
+ r = WRAP(snd_config_search)(pcm_node, "handle_underrun", &node);
|
||||
if (r != -ENOENT) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable pcm_pulse's asynchronous underrun handling. */
|
||||
- r = snd_config_imake_integer(&node, "handle_underrun", 0);
|
||||
+ r = WRAP(snd_config_imake_integer)(&node, "handle_underrun", 0);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
- r = snd_config_add(pcm_node, node);
|
||||
+ r = WRAP(snd_config_add)(pcm_node, node);
|
||||
if (r < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -667,7 +716,7 @@ init_local_config_with_workaround(char const * pcm_name)
|
||||
return lconf;
|
||||
} while (0);
|
||||
|
||||
- snd_config_delete(lconf);
|
||||
+ WRAP(snd_config_delete)(lconf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -679,9 +728,9 @@ alsa_locked_pcm_open(snd_pcm_t ** pcm, char const * pcm_name, snd_pcm_stream_t s
|
||||
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
if (local_config) {
|
||||
- r = snd_pcm_open_lconf(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config);
|
||||
+ r = WRAP(snd_pcm_open_lconf)(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config);
|
||||
} else {
|
||||
- r = snd_pcm_open(pcm, pcm_name, stream, SND_PCM_NONBLOCK);
|
||||
+ r = WRAP(snd_pcm_open)(pcm, pcm_name, stream, SND_PCM_NONBLOCK);
|
||||
}
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
|
||||
@@ -694,7 +743,7 @@ alsa_locked_pcm_close(snd_pcm_t * pcm)
|
||||
int r;
|
||||
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
- r = snd_pcm_close(pcm);
|
||||
+ r = WRAP(snd_pcm_close)(pcm);
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
|
||||
return r;
|
||||
@@ -750,6 +799,7 @@ silent_error_handler(char const * file, int line, char const * function,
|
||||
alsa_init(cubeb ** context, char const * context_name)
|
||||
{
|
||||
(void)context_name;
|
||||
+ void * libasound = NULL;
|
||||
cubeb * ctx;
|
||||
int r;
|
||||
int i;
|
||||
@@ -760,9 +810,27 @@ alsa_init(cubeb ** context, char const * context_name)
|
||||
assert(context);
|
||||
*context = NULL;
|
||||
|
||||
+#ifndef DISABLE_LIBASOUND_DLOPEN
|
||||
+ libasound = dlopen("libasound.so", RTLD_LAZY);
|
||||
+ if (!libasound) {
|
||||
+ return CUBEB_ERROR;
|
||||
+ }
|
||||
+
|
||||
+#define LOAD(x) { \
|
||||
+ cubeb_##x = dlsym(libasound, #x); \
|
||||
+ if (!cubeb_##x) { \
|
||||
+ dlclose(libasound); \
|
||||
+ return CUBEB_ERROR; \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+ LIBASOUND_API_VISIT(LOAD);
|
||||
+#undef LOAD
|
||||
+#endif
|
||||
+
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
if (!cubeb_alsa_error_handler_set) {
|
||||
- snd_lib_error_set_handler(silent_error_handler);
|
||||
+ WRAP(snd_lib_error_set_handler)(silent_error_handler);
|
||||
cubeb_alsa_error_handler_set = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
@@ -771,6 +839,7 @@ alsa_init(cubeb ** context, char const * context_name)
|
||||
assert(ctx);
|
||||
|
||||
ctx->ops = &alsa_ops;
|
||||
+ ctx->libasound = libasound;
|
||||
|
||||
r = pthread_mutex_init(&ctx->mutex, NULL);
|
||||
assert(r == 0);
|
||||
@@ -819,7 +888,7 @@ alsa_init(cubeb ** context, char const * context_name)
|
||||
config fails with EINVAL, the PA PCM is too old for this workaround. */
|
||||
if (r == -EINVAL) {
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
- snd_config_delete(ctx->local_config);
|
||||
+ WRAP(snd_config_delete)(ctx->local_config);
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
ctx->local_config = NULL;
|
||||
} else if (r >= 0) {
|
||||
@@ -861,10 +930,14 @@ alsa_destroy(cubeb * ctx)
|
||||
|
||||
if (ctx->local_config) {
|
||||
pthread_mutex_lock(&cubeb_alsa_mutex);
|
||||
- snd_config_delete(ctx->local_config);
|
||||
+ WRAP(snd_config_delete)(ctx->local_config);
|
||||
pthread_mutex_unlock(&cubeb_alsa_mutex);
|
||||
}
|
||||
|
||||
+ if (ctx->libasound) {
|
||||
+ dlclose(ctx->libasound);
|
||||
+ }
|
||||
+
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
@@ -948,7 +1021,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_nonblock(stm->pcm, 1);
|
||||
+ r = WRAP(snd_pcm_nonblock)(stm->pcm, 1);
|
||||
assert(r == 0);
|
||||
|
||||
latency_us = latency_frames * 1e6 / stm->params.rate;
|
||||
@@ -961,7 +1034,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream
|
||||
latency_us = latency_us < min_latency ? min_latency: latency_us;
|
||||
}
|
||||
|
||||
- r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
+ r = WRAP(snd_pcm_set_params)(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
stm->params.channels, stm->params.rate, 1,
|
||||
latency_us);
|
||||
if (r < 0) {
|
||||
@@ -969,20 +1042,20 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream
|
||||
return CUBEB_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
- r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &period_size);
|
||||
+ r = WRAP(snd_pcm_get_params)(stm->pcm, &stm->buffer_size, &period_size);
|
||||
assert(r == 0);
|
||||
|
||||
/* Double internal buffer size to have enough space when waiting for the other side of duplex connection */
|
||||
stm->buffer_size *= 2;
|
||||
- stm->buffer = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, stm->buffer_size));
|
||||
+ stm->buffer = calloc(1, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->buffer_size));
|
||||
assert(stm->buffer);
|
||||
|
||||
- stm->nfds = snd_pcm_poll_descriptors_count(stm->pcm);
|
||||
+ stm->nfds = WRAP(snd_pcm_poll_descriptors_count)(stm->pcm);
|
||||
assert(stm->nfds > 0);
|
||||
|
||||
stm->saved_fds = calloc(stm->nfds, sizeof(struct pollfd));
|
||||
assert(stm->saved_fds);
|
||||
- r = snd_pcm_poll_descriptors(stm->pcm, stm->saved_fds, stm->nfds);
|
||||
+ r = WRAP(snd_pcm_poll_descriptors)(stm->pcm, stm->saved_fds, stm->nfds);
|
||||
assert((nfds_t) r == stm->nfds);
|
||||
|
||||
if (alsa_register_stream(ctx, stm) != 0) {
|
||||
@@ -1054,7 +1127,7 @@ alsa_stream_destroy(cubeb_stream * stm)
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
if (stm->pcm) {
|
||||
if (stm->state == DRAINING) {
|
||||
- snd_pcm_drain(stm->pcm);
|
||||
+ WRAP(snd_pcm_drain)(stm->pcm);
|
||||
}
|
||||
alsa_locked_pcm_close(stm->pcm);
|
||||
stm->pcm = NULL;
|
||||
@@ -1100,12 +1173,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
|
||||
assert(stm);
|
||||
|
||||
- r = snd_pcm_hw_params_any(stm->pcm, hw_params);
|
||||
+ r = WRAP(snd_pcm_hw_params_any)(stm->pcm, hw_params);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_hw_params_get_channels_max(hw_params, max_channels);
|
||||
+ r = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
@@ -1126,34 +1199,34 @@ alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) {
|
||||
|
||||
/* get a pcm, disabling resampling, so we get a rate the
|
||||
* hardware/dmix/pulse/etc. supports. */
|
||||
- r = snd_pcm_open(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE);
|
||||
+ r = WRAP(snd_pcm_open)(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_hw_params_any(pcm, hw_params);
|
||||
+ r = WRAP(snd_pcm_hw_params_any)(pcm, hw_params);
|
||||
if (r < 0) {
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir);
|
||||
+ r = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &dir);
|
||||
if (r >= 0) {
|
||||
/* There is a default rate: use it. */
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
/* Use a common rate, alsa may adjust it based on hw/etc. capabilities. */
|
||||
*rate = 44100;
|
||||
|
||||
- r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL);
|
||||
+ r = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL);
|
||||
if (r < 0) {
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
- snd_pcm_close(pcm);
|
||||
+ WRAP(snd_pcm_close)(pcm);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
@@ -1186,10 +1259,10 @@ alsa_stream_start(cubeb_stream * stm)
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
/* Capture pcm must be started after initial setup/recover */
|
||||
if (stm->stream_type == SND_PCM_STREAM_CAPTURE &&
|
||||
- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
- snd_pcm_start(stm->pcm);
|
||||
+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) {
|
||||
+ WRAP(snd_pcm_start)(stm->pcm);
|
||||
}
|
||||
- snd_pcm_pause(stm->pcm, 0);
|
||||
+ WRAP(snd_pcm_pause)(stm->pcm, 0);
|
||||
gettimeofday(&stm->last_activity, NULL);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
|
||||
@@ -1229,7 +1302,7 @@ alsa_stream_stop(cubeb_stream * stm)
|
||||
pthread_mutex_unlock(&ctx->mutex);
|
||||
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
- snd_pcm_pause(stm->pcm, 1);
|
||||
+ WRAP(snd_pcm_pause)(stm->pcm, 1);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
|
||||
return CUBEB_OK;
|
||||
@@ -1245,8 +1318,8 @@ alsa_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
|
||||
delay = -1;
|
||||
- if (snd_pcm_state(stm->pcm) != SND_PCM_STATE_RUNNING ||
|
||||
- snd_pcm_delay(stm->pcm, &delay) != 0) {
|
||||
+ if (WRAP(snd_pcm_state)(stm->pcm) != SND_PCM_STATE_RUNNING ||
|
||||
+ WRAP(snd_pcm_delay)(stm->pcm, &delay) != 0) {
|
||||
*position = stm->last_position;
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
return CUBEB_OK;
|
||||
@@ -1271,7 +1344,7 @@ alsa_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
|
||||
snd_pcm_sframes_t delay;
|
||||
/* This function returns the delay in frames until a frame written using
|
||||
snd_pcm_writei is sent to the DAC. The DAC delay should be < 1ms anyways. */
|
||||
- if (snd_pcm_delay(stm->pcm, &delay)) {
|
||||
+ if (WRAP(snd_pcm_delay)(stm->pcm, &delay)) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
diff --git externals/cubeb/src/cubeb_sndio.c externals/cubeb/src/cubeb_sndio.c
|
||||
index 5a43343..c9a31a7 100644
|
||||
--- externals/cubeb/src/cubeb_sndio.c
|
||||
+++ externals/cubeb/src/cubeb_sndio.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
+#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
@@ -22,10 +23,35 @@
|
||||
#define DPR(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
+#ifdef DISABLE_LIBSNDIO_DLOPEN
|
||||
+#define WRAP(x) x
|
||||
+#else
|
||||
+#define WRAP(x) cubeb_##x
|
||||
+#define LIBSNDIO_API_VISIT(X) \
|
||||
+ X(sio_close) \
|
||||
+ X(sio_eof) \
|
||||
+ X(sio_getpar) \
|
||||
+ X(sio_initpar) \
|
||||
+ X(sio_onmove) \
|
||||
+ X(sio_open) \
|
||||
+ X(sio_pollfd) \
|
||||
+ X(sio_read) \
|
||||
+ X(sio_revents) \
|
||||
+ X(sio_setpar) \
|
||||
+ X(sio_start) \
|
||||
+ X(sio_stop) \
|
||||
+ X(sio_write) \
|
||||
+
|
||||
+#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
|
||||
+LIBSNDIO_API_VISIT(MAKE_TYPEDEF);
|
||||
+#undef MAKE_TYPEDEF
|
||||
+#endif
|
||||
+
|
||||
static struct cubeb_ops const sndio_ops;
|
||||
|
||||
struct cubeb {
|
||||
struct cubeb_ops const * ops;
|
||||
+ void * libsndio;
|
||||
};
|
||||
|
||||
struct cubeb_stream {
|
||||
@@ -119,7 +145,7 @@ sndio_mainloop(void *arg)
|
||||
DPR("sndio_mainloop()\n");
|
||||
s->state_cb(s, s->arg, CUBEB_STATE_STARTED);
|
||||
pthread_mutex_lock(&s->mtx);
|
||||
- if (!sio_start(s->hdl)) {
|
||||
+ if (!WRAP(sio_start)(s->hdl)) {
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
return NULL;
|
||||
}
|
||||
@@ -203,7 +229,7 @@ sndio_mainloop(void *arg)
|
||||
events |= POLLIN;
|
||||
if ((s->mode & SIO_PLAY) && pstart < pend)
|
||||
events |= POLLOUT;
|
||||
- nfds = sio_pollfd(s->hdl, pfds, events);
|
||||
+ nfds = WRAP(sio_pollfd)(s->hdl, pfds, events);
|
||||
|
||||
if (nfds > 0) {
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
@@ -213,7 +239,7 @@ sndio_mainloop(void *arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
- revents = sio_revents(s->hdl, pfds);
|
||||
+ revents = WRAP(sio_revents)(s->hdl, pfds);
|
||||
|
||||
if (revents & POLLHUP) {
|
||||
state = CUBEB_STATE_ERROR;
|
||||
@@ -221,8 +247,8 @@ sndio_mainloop(void *arg)
|
||||
}
|
||||
|
||||
if (revents & POLLOUT) {
|
||||
- n = sio_write(s->hdl, s->pbuf + pstart, pend - pstart);
|
||||
- if (n == 0 && sio_eof(s->hdl)) {
|
||||
+ n = WRAP(sio_write)(s->hdl, s->pbuf + pstart, pend - pstart);
|
||||
+ if (n == 0 && WRAP(sio_eof)(s->hdl)) {
|
||||
DPR("sndio_mainloop() werr\n");
|
||||
state = CUBEB_STATE_ERROR;
|
||||
break;
|
||||
@@ -231,8 +257,8 @@ sndio_mainloop(void *arg)
|
||||
}
|
||||
|
||||
if (revents & POLLIN) {
|
||||
- n = sio_read(s->hdl, s->rbuf + rstart, rend - rstart);
|
||||
- if (n == 0 && sio_eof(s->hdl)) {
|
||||
+ n = WRAP(sio_read)(s->hdl, s->rbuf + rstart, rend - rstart);
|
||||
+ if (n == 0 && WRAP(sio_eof)(s->hdl)) {
|
||||
DPR("sndio_mainloop() rerr\n");
|
||||
state = CUBEB_STATE_ERROR;
|
||||
break;
|
||||
@@ -244,7 +270,7 @@ sndio_mainloop(void *arg)
|
||||
if (prime > 0 && (s->mode & SIO_REC))
|
||||
rstart = rend;
|
||||
}
|
||||
- sio_stop(s->hdl);
|
||||
+ WRAP(sio_stop)(s->hdl);
|
||||
s->hwpos = s->swpos;
|
||||
pthread_mutex_unlock(&s->mtx);
|
||||
s->state_cb(s, s->arg, state);
|
||||
@@ -254,8 +280,31 @@ sndio_mainloop(void *arg)
|
||||
/*static*/ int
|
||||
sndio_init(cubeb **context, char const *context_name)
|
||||
{
|
||||
+ void * libsndio = NULL;
|
||||
+
|
||||
+#ifndef DISABLE_LIBSNDIO_DLOPEN
|
||||
+ libsndio = dlopen("libsndio.so", RTLD_LAZY);
|
||||
+ if (!libsndio) {
|
||||
+ DPR("sndio_init(%s) failed dlopen(libsndio.so)\n", context_name);
|
||||
+ return CUBEB_ERROR;
|
||||
+ }
|
||||
+
|
||||
+#define LOAD(x) { \
|
||||
+ cubeb_##x = dlsym(libsndio, #x); \
|
||||
+ if (!cubeb_##x) { \
|
||||
+ DPR("sndio_init(%s) failed dlsym(%s)\n", context_name, #x); \
|
||||
+ dlclose(libsndio); \
|
||||
+ return CUBEB_ERROR; \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+ LIBSNDIO_API_VISIT(LOAD);
|
||||
+#undef LOAD
|
||||
+#endif
|
||||
+
|
||||
DPR("sndio_init(%s)\n", context_name);
|
||||
*context = malloc(sizeof(*context));
|
||||
+ (*context)->libsndio = libsndio;
|
||||
(*context)->ops = &sndio_ops;
|
||||
(void)context_name;
|
||||
return CUBEB_OK;
|
||||
@@ -271,6 +320,8 @@ static void
|
||||
sndio_destroy(cubeb *context)
|
||||
{
|
||||
DPR("sndio_destroy()\n");
|
||||
+ if (context->libsndio)
|
||||
+ dlclose(context->libsndio);
|
||||
free(context);
|
||||
}
|
||||
|
||||
@@ -323,12 +374,12 @@ sndio_stream_init(cubeb * context,
|
||||
goto err;
|
||||
}
|
||||
s->context = context;
|
||||
- s->hdl = sio_open(NULL, s->mode, 1);
|
||||
+ s->hdl = WRAP(sio_open)(NULL, s->mode, 1);
|
||||
if (s->hdl == NULL) {
|
||||
DPR("sndio_stream_init(), sio_open() failed\n");
|
||||
goto err;
|
||||
}
|
||||
- sio_initpar(&wpar);
|
||||
+ WRAP(sio_initpar)(&wpar);
|
||||
wpar.sig = 1;
|
||||
wpar.bits = 16;
|
||||
switch (format) {
|
||||
@@ -351,7 +402,7 @@ sndio_stream_init(cubeb * context,
|
||||
if (s->mode & SIO_PLAY)
|
||||
wpar.pchan = output_stream_params->channels;
|
||||
wpar.appbufsz = latency_frames;
|
||||
- if (!sio_setpar(s->hdl, &wpar) || !sio_getpar(s->hdl, &rpar)) {
|
||||
+ if (!WRAP(sio_setpar)(s->hdl, &wpar) || !WRAP(sio_getpar)(s->hdl, &rpar)) {
|
||||
DPR("sndio_stream_init(), sio_setpar() failed\n");
|
||||
goto err;
|
||||
}
|
||||
@@ -362,7 +413,7 @@ sndio_stream_init(cubeb * context,
|
||||
DPR("sndio_stream_init() unsupported params\n");
|
||||
goto err;
|
||||
}
|
||||
- sio_onmove(s->hdl, sndio_onmove, s);
|
||||
+ WRAP(sio_onmove)(s->hdl, sndio_onmove, s);
|
||||
s->active = 0;
|
||||
s->nfr = rpar.round;
|
||||
s->rbpf = rpar.bps * rpar.rchan;
|
||||
@@ -400,7 +451,7 @@ sndio_stream_init(cubeb * context,
|
||||
return CUBEB_OK;
|
||||
err:
|
||||
if (s->hdl)
|
||||
- sio_close(s->hdl);
|
||||
+ WRAP(sio_close)(s->hdl);
|
||||
if (s->pbuf)
|
||||
free(s->pbuf);
|
||||
if (s->rbuf)
|
||||
@@ -446,7 +497,7 @@ static void
|
||||
sndio_stream_destroy(cubeb_stream *s)
|
||||
{
|
||||
DPR("sndio_stream_destroy()\n");
|
||||
- sio_close(s->hdl);
|
||||
+ WRAP(sio_close)(s->hdl);
|
||||
if (s->mode & SIO_PLAY)
|
||||
free(s->pbuf);
|
||||
if (s->mode & SIO_REC)
|
Loading…
Reference in New Issue
Block a user