diff options
author | Jan Beich <[email protected]> | 2019-09-05 16:41:02 +0000 |
---|---|---|
committer | Matthew Gregan <[email protected]> | 2019-09-09 13:49:48 +1200 |
commit | edf8c13d00e235f5741f8b17c8b804fdb1e26d8f (patch) | |
tree | 5028930b522805c5c04dff1e6b68d2502cc89836 | |
parent | 7b7bdfc2fe7e926f1a9eec482687b2dd2404d123 (diff) | |
download | cubeb-edf8c13d00e235f5741f8b17c8b804fdb1e26d8f.tar.gz cubeb-edf8c13d00e235f5741f8b17c8b804fdb1e26d8f.zip |
sndio: don't depend on libsndio by default
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/cubeb_sndio.c | 79 |
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) |