aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJan Beich <[email protected]>2019-09-05 16:41:02 +0000
committerMatthew Gregan <[email protected]>2019-09-09 13:49:48 +1200
commitedf8c13d00e235f5741f8b17c8b804fdb1e26d8f (patch)
tree5028930b522805c5c04dff1e6b68d2502cc89836
parent7b7bdfc2fe7e926f1a9eec482687b2dd2404d123 (diff)
downloadcubeb-edf8c13d00e235f5741f8b17c8b804fdb1e26d8f.tar.gz
cubeb-edf8c13d00e235f5741f8b17c8b804fdb1e26d8f.zip
sndio: don't depend on libsndio by default
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/cubeb_sndio.c79
2 files changed, 66 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d567c59..9138500 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -212,7 +212,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 pthread)
+ target_link_libraries(cubeb PRIVATE pthread)
endif()
check_include_files(sys/audioio.h USE_SUN)
diff --git a/src/cubeb_sndio.c b/src/cubeb_sndio.c
index c90a0e9..9ba51b3 100644
--- a/src/cubeb_sndio.c
+++ b/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)