mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 02:15:47 -04:00
dep/cubeb: Update to dc511c6
This commit is contained in:
@ -4,44 +4,46 @@
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#include "cubeb-internal.h"
|
||||
#include "cubeb/cubeb.h"
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <sndio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "cubeb-internal.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(CUBEB_SNDIO_DEBUG)
|
||||
#define DPR(...) fprintf(stderr, __VA_ARGS__);
|
||||
#else
|
||||
#define DPR(...) do {} while(0)
|
||||
#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_nfds) \
|
||||
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 WRAP(x) (*cubeb_##x)
|
||||
#define LIBSNDIO_API_VISIT(X) \
|
||||
X(sio_close) \
|
||||
X(sio_eof) \
|
||||
X(sio_getpar) \
|
||||
X(sio_initpar) \
|
||||
X(sio_nfds) \
|
||||
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);
|
||||
@ -58,33 +60,33 @@ struct cubeb {
|
||||
struct cubeb_stream {
|
||||
/* Note: Must match cubeb_stream layout in cubeb.c. */
|
||||
cubeb * context;
|
||||
void * arg; /* user arg to {data,state}_cb */
|
||||
void * arg; /* user arg to {data,state}_cb */
|
||||
/**/
|
||||
pthread_t th; /* to run real-time audio i/o */
|
||||
pthread_mutex_t mtx; /* protects hdl and pos */
|
||||
struct sio_hdl *hdl; /* link us to sndio */
|
||||
int mode; /* bitmap of SIO_{PLAY,REC} */
|
||||
int active; /* cubec_start() called */
|
||||
int conv; /* need float->s16 conversion */
|
||||
unsigned char *rbuf; /* rec data consumed from here */
|
||||
unsigned char *pbuf; /* play data is prepared here */
|
||||
unsigned int nfr; /* number of frames in ibuf and obuf */
|
||||
unsigned int rbpf; /* rec bytes per frame */
|
||||
unsigned int pbpf; /* play bytes per frame */
|
||||
unsigned int rchan; /* number of rec channels */
|
||||
unsigned int pchan; /* number of play channels */
|
||||
unsigned int nblks; /* number of blocks in the buffer */
|
||||
uint64_t hwpos; /* frame number Joe hears right now */
|
||||
uint64_t swpos; /* number of frames produced/consumed */
|
||||
cubeb_data_callback data_cb; /* cb to preapare data */
|
||||
cubeb_state_callback state_cb; /* cb to notify about state changes */
|
||||
float volume; /* current volume */
|
||||
pthread_t th; /* to run real-time audio i/o */
|
||||
pthread_mutex_t mtx; /* protects hdl and pos */
|
||||
struct sio_hdl * hdl; /* link us to sndio */
|
||||
int mode; /* bitmap of SIO_{PLAY,REC} */
|
||||
int active; /* cubec_start() called */
|
||||
int conv; /* need float->s16 conversion */
|
||||
unsigned char * rbuf; /* rec data consumed from here */
|
||||
unsigned char * pbuf; /* play data is prepared here */
|
||||
unsigned int nfr; /* number of frames in ibuf and obuf */
|
||||
unsigned int rbpf; /* rec bytes per frame */
|
||||
unsigned int pbpf; /* play bytes per frame */
|
||||
unsigned int rchan; /* number of rec channels */
|
||||
unsigned int pchan; /* number of play channels */
|
||||
unsigned int nblks; /* number of blocks in the buffer */
|
||||
uint64_t hwpos; /* frame number Joe hears right now */
|
||||
uint64_t swpos; /* number of frames produced/consumed */
|
||||
cubeb_data_callback data_cb; /* cb to preapare data */
|
||||
cubeb_state_callback state_cb; /* cb to notify about state changes */
|
||||
float volume; /* current volume */
|
||||
};
|
||||
|
||||
static void
|
||||
s16_setvol(void *ptr, long nsamp, float volume)
|
||||
s16_setvol(void * ptr, long nsamp, float volume)
|
||||
{
|
||||
int16_t *dst = ptr;
|
||||
int16_t * dst = ptr;
|
||||
int32_t mult = volume * 32768;
|
||||
int32_t s;
|
||||
|
||||
@ -96,10 +98,10 @@ s16_setvol(void *ptr, long nsamp, float volume)
|
||||
}
|
||||
|
||||
static void
|
||||
float_to_s16(void *ptr, long nsamp, float volume)
|
||||
float_to_s16(void * ptr, long nsamp, float volume)
|
||||
{
|
||||
int16_t *dst = ptr;
|
||||
float *src = ptr;
|
||||
int16_t * dst = ptr;
|
||||
float * src = ptr;
|
||||
float mult = volume * 32768;
|
||||
int s;
|
||||
|
||||
@ -114,10 +116,10 @@ float_to_s16(void *ptr, long nsamp, float volume)
|
||||
}
|
||||
|
||||
static void
|
||||
s16_to_float(void *ptr, long nsamp)
|
||||
s16_to_float(void * ptr, long nsamp)
|
||||
{
|
||||
int16_t *src = ptr;
|
||||
float *dst = ptr;
|
||||
int16_t * src = ptr;
|
||||
float * dst = ptr;
|
||||
|
||||
src += nsamp;
|
||||
dst += nsamp;
|
||||
@ -133,9 +135,9 @@ sndio_get_device()
|
||||
* On other platforms default to sndio devices,
|
||||
* so cubebs other backends can be used instead.
|
||||
*/
|
||||
const char *dev = getenv("AUDIODEVICE");
|
||||
const char * dev = getenv("AUDIODEVICE");
|
||||
if (dev == NULL || *dev == '\0')
|
||||
return "snd/0";
|
||||
return "snd/0";
|
||||
return dev;
|
||||
#else
|
||||
return SIO_DEVANY;
|
||||
@ -143,26 +145,26 @@ sndio_get_device()
|
||||
}
|
||||
|
||||
static void
|
||||
sndio_onmove(void *arg, int delta)
|
||||
sndio_onmove(void * arg, int delta)
|
||||
{
|
||||
cubeb_stream *s = (cubeb_stream *)arg;
|
||||
cubeb_stream * s = (cubeb_stream *)arg;
|
||||
|
||||
s->hwpos += delta;
|
||||
}
|
||||
|
||||
static void *
|
||||
sndio_mainloop(void *arg)
|
||||
sndio_mainloop(void * arg)
|
||||
{
|
||||
struct pollfd *pfds;
|
||||
cubeb_stream *s = arg;
|
||||
struct pollfd * pfds;
|
||||
cubeb_stream * s = arg;
|
||||
int n, eof = 0, prime, nfds, events, revents, state = CUBEB_STATE_STARTED;
|
||||
size_t pstart = 0, pend = 0, rstart = 0, rend = 0;
|
||||
long nfr;
|
||||
|
||||
nfds = WRAP(sio_nfds)(s->hdl);
|
||||
pfds = calloc(nfds, sizeof (struct pollfd));
|
||||
pfds = calloc(nfds, sizeof(struct pollfd));
|
||||
if (pfds == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
DPR("sndio_mainloop()\n");
|
||||
s->state_cb(s, s->arg, CUBEB_STATE_STARTED);
|
||||
@ -196,7 +198,7 @@ sndio_mainloop(void *arg)
|
||||
|
||||
/* do we have a complete block? */
|
||||
if ((!(s->mode & SIO_PLAY) || pstart == pend) &&
|
||||
(!(s->mode & SIO_REC) || rstart == rend)) {
|
||||
(!(s->mode & SIO_REC) || rstart == rend)) {
|
||||
|
||||
if (eof) {
|
||||
DPR("sndio_mainloop() drained\n");
|
||||
@ -224,7 +226,7 @@ sndio_mainloop(void *arg)
|
||||
if (!(s->mode & SIO_PLAY) || nfr == 0) {
|
||||
state = CUBEB_STATE_DRAINED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* need to write (aka drain) the partial play block we got */
|
||||
pend = nfr * s->pbpf;
|
||||
@ -302,10 +304,10 @@ sndio_mainloop(void *arg)
|
||||
}
|
||||
|
||||
/*static*/ int
|
||||
sndio_init(cubeb **context, char const *context_name)
|
||||
sndio_init(cubeb ** context, char const * context_name)
|
||||
{
|
||||
void * libsndio = NULL;
|
||||
struct sio_hdl *hdl;
|
||||
struct sio_hdl * hdl;
|
||||
|
||||
assert(context);
|
||||
|
||||
@ -319,13 +321,14 @@ sndio_init(cubeb **context, char const *context_name)
|
||||
}
|
||||
}
|
||||
|
||||
#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; \
|
||||
} \
|
||||
#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);
|
||||
@ -342,7 +345,7 @@ sndio_init(cubeb **context, char const *context_name)
|
||||
DPR("sndio_init(%s)\n", context_name);
|
||||
*context = malloc(sizeof(**context));
|
||||
if (*context == NULL)
|
||||
return CUBEB_ERROR;
|
||||
return CUBEB_ERROR;
|
||||
(*context)->libsndio = libsndio;
|
||||
(*context)->ops = &sndio_ops;
|
||||
(void)context_name;
|
||||
@ -350,13 +353,13 @@ sndio_init(cubeb **context, char const *context_name)
|
||||
}
|
||||
|
||||
static char const *
|
||||
sndio_get_backend_id(cubeb *context)
|
||||
sndio_get_backend_id(cubeb * context)
|
||||
{
|
||||
return "sndio";
|
||||
}
|
||||
|
||||
static void
|
||||
sndio_destroy(cubeb *context)
|
||||
sndio_destroy(cubeb * context)
|
||||
{
|
||||
DPR("sndio_destroy()\n");
|
||||
if (context->libsndio)
|
||||
@ -365,19 +368,16 @@ sndio_destroy(cubeb *context)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_stream_init(cubeb * context,
|
||||
cubeb_stream ** stream,
|
||||
char const * stream_name,
|
||||
cubeb_devid input_device,
|
||||
sndio_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
char const * stream_name, cubeb_devid input_device,
|
||||
cubeb_stream_params * input_stream_params,
|
||||
cubeb_devid output_device,
|
||||
cubeb_stream_params * output_stream_params,
|
||||
unsigned int latency_frames,
|
||||
cubeb_data_callback data_callback,
|
||||
cubeb_state_callback state_callback,
|
||||
void *user_ptr)
|
||||
cubeb_state_callback state_callback, void * user_ptr)
|
||||
{
|
||||
cubeb_stream *s;
|
||||
cubeb_stream * s;
|
||||
struct sio_par wpar, rpar;
|
||||
cubeb_sample_format format;
|
||||
int rate;
|
||||
@ -445,8 +445,8 @@ sndio_stream_init(cubeb * context,
|
||||
DPR("sndio_stream_init(), sio_setpar() failed\n");
|
||||
goto err;
|
||||
}
|
||||
if (rpar.bits != wpar.bits || rpar.le != wpar.le ||
|
||||
rpar.sig != wpar.sig || rpar.rate != wpar.rate ||
|
||||
if (rpar.bits != wpar.bits || rpar.le != wpar.le || rpar.sig != wpar.sig ||
|
||||
rpar.rate != wpar.rate ||
|
||||
((s->mode & SIO_REC) && rpar.rchan != wpar.rchan) ||
|
||||
((s->mode & SIO_PLAY) && rpar.pchan != wpar.pchan)) {
|
||||
DPR("sndio_stream_init() unsupported params\n");
|
||||
@ -522,7 +522,8 @@ sndio_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latency_frames)
|
||||
sndio_get_min_latency(cubeb * ctx, cubeb_stream_params params,
|
||||
uint32_t * latency_frames)
|
||||
{
|
||||
/*
|
||||
* We've no device-independent minimum latency.
|
||||
@ -533,7 +534,7 @@ sndio_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latenc
|
||||
}
|
||||
|
||||
static void
|
||||
sndio_stream_destroy(cubeb_stream *s)
|
||||
sndio_stream_destroy(cubeb_stream * s)
|
||||
{
|
||||
DPR("sndio_stream_destroy()\n");
|
||||
WRAP(sio_close)(s->hdl);
|
||||
@ -545,7 +546,7 @@ sndio_stream_destroy(cubeb_stream *s)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_stream_start(cubeb_stream *s)
|
||||
sndio_stream_start(cubeb_stream * s)
|
||||
{
|
||||
int err;
|
||||
|
||||
@ -560,9 +561,9 @@ sndio_stream_start(cubeb_stream *s)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_stream_stop(cubeb_stream *s)
|
||||
sndio_stream_stop(cubeb_stream * s)
|
||||
{
|
||||
void *dummy;
|
||||
void * dummy;
|
||||
|
||||
DPR("sndio_stream_stop()\n");
|
||||
if (s->active) {
|
||||
@ -573,7 +574,7 @@ sndio_stream_stop(cubeb_stream *s)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_stream_get_position(cubeb_stream *s, uint64_t *p)
|
||||
sndio_stream_get_position(cubeb_stream * s, uint64_t * p)
|
||||
{
|
||||
pthread_mutex_lock(&s->mtx);
|
||||
DPR("sndio_stream_get_position() %" PRId64 "\n", s->hwpos);
|
||||
@ -583,7 +584,7 @@ sndio_stream_get_position(cubeb_stream *s, uint64_t *p)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_stream_set_volume(cubeb_stream *s, float volume)
|
||||
sndio_stream_set_volume(cubeb_stream * s, float volume)
|
||||
{
|
||||
DPR("sndio_stream_set_volume(%f)\n", volume);
|
||||
pthread_mutex_lock(&s->mtx);
|
||||
@ -606,27 +607,27 @@ sndio_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
|
||||
}
|
||||
|
||||
static int
|
||||
sndio_enumerate_devices(cubeb *context, cubeb_device_type type,
|
||||
cubeb_device_collection *collection)
|
||||
sndio_enumerate_devices(cubeb * context, cubeb_device_type type,
|
||||
cubeb_device_collection * collection)
|
||||
{
|
||||
static char dev[] = SIO_DEVANY;
|
||||
cubeb_device_info *device;
|
||||
cubeb_device_info * device;
|
||||
|
||||
device = malloc(sizeof(cubeb_device_info));
|
||||
if (device == NULL)
|
||||
return CUBEB_ERROR;
|
||||
|
||||
device->devid = dev; /* passed to stream_init() */
|
||||
device->device_id = dev; /* printable in UI */
|
||||
device->friendly_name = dev; /* same, but friendly */
|
||||
device->group_id = dev; /* actual device if full-duplex */
|
||||
device->vendor_name = NULL; /* may be NULL */
|
||||
device->type = type; /* Input/Output */
|
||||
device->devid = dev; /* passed to stream_init() */
|
||||
device->device_id = dev; /* printable in UI */
|
||||
device->friendly_name = dev; /* same, but friendly */
|
||||
device->group_id = dev; /* actual device if full-duplex */
|
||||
device->vendor_name = NULL; /* may be NULL */
|
||||
device->type = type; /* Input/Output */
|
||||
device->state = CUBEB_DEVICE_STATE_ENABLED;
|
||||
device->preferred = CUBEB_DEVICE_PREF_ALL;
|
||||
device->format = CUBEB_DEVICE_FMT_S16NE;
|
||||
device->default_format = CUBEB_DEVICE_FMT_S16NE;
|
||||
device->max_channels = 16;
|
||||
device->max_channels = (type == CUBEB_DEVICE_TYPE_INPUT) ? 2 : 8;
|
||||
device->default_rate = 48000;
|
||||
device->min_rate = 4000;
|
||||
device->max_rate = 192000;
|
||||
@ -639,32 +640,30 @@ sndio_enumerate_devices(cubeb *context, cubeb_device_type type,
|
||||
|
||||
static int
|
||||
sndio_device_collection_destroy(cubeb * context,
|
||||
cubeb_device_collection * collection)
|
||||
cubeb_device_collection * collection)
|
||||
{
|
||||
free(collection->device);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const sndio_ops = {
|
||||
.init = sndio_init,
|
||||
.get_backend_id = sndio_get_backend_id,
|
||||
.get_max_channel_count = sndio_get_max_channel_count,
|
||||
.get_min_latency = sndio_get_min_latency,
|
||||
.get_preferred_sample_rate = sndio_get_preferred_sample_rate,
|
||||
.enumerate_devices = sndio_enumerate_devices,
|
||||
.device_collection_destroy = sndio_device_collection_destroy,
|
||||
.destroy = sndio_destroy,
|
||||
.stream_init = sndio_stream_init,
|
||||
.stream_destroy = sndio_stream_destroy,
|
||||
.stream_start = sndio_stream_start,
|
||||
.stream_stop = sndio_stream_stop,
|
||||
.stream_reset_default_device = NULL,
|
||||
.stream_get_position = sndio_stream_get_position,
|
||||
.stream_get_latency = sndio_stream_get_latency,
|
||||
.stream_set_volume = sndio_stream_set_volume,
|
||||
.stream_set_name = NULL,
|
||||
.stream_get_current_device = NULL,
|
||||
.stream_device_destroy = NULL,
|
||||
.stream_register_device_changed_callback = NULL,
|
||||
.register_device_collection_changed = NULL
|
||||
};
|
||||
.init = sndio_init,
|
||||
.get_backend_id = sndio_get_backend_id,
|
||||
.get_max_channel_count = sndio_get_max_channel_count,
|
||||
.get_min_latency = sndio_get_min_latency,
|
||||
.get_preferred_sample_rate = sndio_get_preferred_sample_rate,
|
||||
.enumerate_devices = sndio_enumerate_devices,
|
||||
.device_collection_destroy = sndio_device_collection_destroy,
|
||||
.destroy = sndio_destroy,
|
||||
.stream_init = sndio_stream_init,
|
||||
.stream_destroy = sndio_stream_destroy,
|
||||
.stream_start = sndio_stream_start,
|
||||
.stream_stop = sndio_stream_stop,
|
||||
.stream_get_position = sndio_stream_get_position,
|
||||
.stream_get_latency = sndio_stream_get_latency,
|
||||
.stream_set_volume = sndio_stream_set_volume,
|
||||
.stream_set_name = NULL,
|
||||
.stream_get_current_device = NULL,
|
||||
.stream_device_destroy = NULL,
|
||||
.stream_register_device_changed_callback = NULL,
|
||||
.register_device_collection_changed = NULL};
|
||||
|
Reference in New Issue
Block a user