Bug 1744973 - Update libcubeb to revision 773f16b7e. r=cubeb-reviewers,chunmin

Differential Revision: https://phabricator.services.mozilla.com/D133197
This commit is contained in:
Paul Adenot 2021-12-08 17:43:11 +00:00
Родитель 9477e32f16
Коммит 8846c0abf1
9 изменённых файлов: 176 добавлений и 176 удалений

Просмотреть файл

@ -19,5 +19,5 @@ origin:
license: "ISC"
# update.sh will update this value
release: "ef5a1ffde99fe98ba0c28dab5128476e8aa384b8 (2021-10-12 08:09:34 +1300)"
release: "773f16b7ea308392c05be3e290163d1f636e6024-dirty (2021-12-08 11:09:25 +1300)"

Просмотреть файл

@ -1,6 +1,8 @@
#include "cubeb-jni-instances.h"
/* clang-format off */
#include "jni.h"
#include <assert.h>
#include "cubeb-jni-instances.h"
/* clang-format on */
#define AUDIO_STREAM_TYPE_MUSIC 3

Просмотреть файл

@ -24,7 +24,7 @@
#ifdef DISABLE_LIBAAUDIO_DLOPEN
#define WRAP(x) x
#else
#define WRAP(x) cubeb_##x
#define WRAP(x) (*cubeb_##x)
#define LIBAAUDIO_API_VISIT(X) \
X(AAudio_convertResultToText) \
X(AAudio_convertStreamStateToText) \
@ -78,6 +78,7 @@
// X(AAudioStream_getContentType) \
// X(AAudioStream_getInputPreset) \
// X(AAudioStream_getSessionId) \
// END: not needed or added later on
#define MAKE_TYPEDEF(x) static decltype(x) * cubeb_##x;
LIBAAUDIO_API_VISIT(MAKE_TYPEDEF)
@ -1475,7 +1476,7 @@ aaudio_init(cubeb ** context, char const * /* context_name */)
#define LOAD(x) \
{ \
WRAP(x) = (decltype(WRAP(x)))(dlsym(libaaudio, #x)); \
cubeb_##x = (decltype(x) *)(dlsym(libaaudio, #x)); \
if (!WRAP(x)) { \
LOG("AAudio: Failed to load %s", #x); \
dlclose(libaaudio); \

Просмотреть файл

@ -22,7 +22,7 @@
#ifdef DISABLE_LIBASOUND_DLOPEN
#define WRAP(x) x
#else
#define WRAP(x) cubeb_##x
#define WRAP(x) (*cubeb_##x)
#define LIBASOUND_API_VISIT(X) \
X(snd_config) \
X(snd_config_add) \
@ -660,11 +660,11 @@ init_local_config_with_workaround(char const * pcm_name)
lconf = NULL;
if (*WRAP(snd_config) == NULL) {
if (WRAP(snd_config) == NULL) {
return NULL;
}
r = WRAP(snd_config_copy)(&lconf, *WRAP(snd_config));
r = WRAP(snd_config_copy)(&lconf, WRAP(snd_config));
if (r < 0) {
return NULL;
}

Просмотреть файл

@ -26,6 +26,10 @@
#include <jack/jack.h>
#include <jack/statistics.h>
#ifdef DISABLE_LIBJACK_DLOPEN
#define WRAP(x) x
#else
#define WRAP(x) (*api_##x)
#define JACK_API_VISIT(X) \
X(jack_activate) \
X(jack_client_close) \
@ -49,6 +53,8 @@
#define IMPORT_FUNC(x) static decltype(x) * api_##x;
JACK_API_VISIT(IMPORT_FUNC);
#undef IMPORT_FUNC
#endif
#define JACK_DEFAULT_IN "JACK capture"
#define JACK_DEFAULT_OUT "JACK playback"
@ -235,6 +241,7 @@ struct cubeb {
static int
load_jack_lib(cubeb * context)
{
#ifndef DISABLE_LIBJACK_DLOPEN
#ifdef __APPLE__
context->libjack = dlopen("libjack.0.dylib", RTLD_LAZY);
context->libjack = dlopen("/usr/local/lib/libjack.0.dylib", RTLD_LAZY);
@ -265,7 +272,7 @@ load_jack_lib(cubeb * context)
JACK_API_VISIT(LOAD);
#undef LOAD
#endif
return CUBEB_OK;
}
@ -273,18 +280,18 @@ static void
cbjack_connect_port_out(cubeb_stream * stream, const size_t out_port,
const char * const phys_in_port)
{
const char * src_port = api_jack_port_name(stream->output_ports[out_port]);
const char * src_port = WRAP(jack_port_name)(stream->output_ports[out_port]);
api_jack_connect(stream->context->jack_client, src_port, phys_in_port);
WRAP(jack_connect)(stream->context->jack_client, src_port, phys_in_port);
}
static void
cbjack_connect_port_in(cubeb_stream * stream, const char * const phys_out_port,
size_t in_port)
{
const char * src_port = api_jack_port_name(stream->input_ports[in_port]);
const char * src_port = WRAP(jack_port_name)(stream->input_ports[in_port]);
api_jack_connect(stream->context->jack_client, phys_out_port, src_port);
WRAP(jack_connect)(stream->context->jack_client, phys_out_port, src_port);
}
static int
@ -293,11 +300,11 @@ cbjack_connect_ports(cubeb_stream * stream,
{
int r = CUBEB_ERROR;
const char ** phys_in_ports =
api_jack_get_ports(stream->context->jack_client, NULL, NULL,
JackPortIsInput | JackPortIsPhysical);
WRAP(jack_get_ports)(stream->context->jack_client, NULL, NULL,
JackPortIsInput | JackPortIsPhysical);
const char ** phys_out_ports =
api_jack_get_ports(stream->context->jack_client, NULL, NULL,
JackPortIsOutput | JackPortIsPhysical);
WRAP(jack_get_ports)(stream->context->jack_client, NULL, NULL,
JackPortIsOutput | JackPortIsPhysical);
if (phys_in_ports == NULL || *phys_in_ports == NULL ||
options & CBJACK_CP_OPTIONS_SKIP_OUTPUT) {
@ -330,10 +337,10 @@ skipplayback:
r = CUBEB_OK;
end:
if (phys_out_ports) {
api_jack_free(phys_out_ports);
WRAP(jack_free)(phys_out_ports);
}
if (phys_in_ports) {
api_jack_free(phys_in_ports);
WRAP(jack_free)(phys_in_ports);
}
return r;
}
@ -343,7 +350,7 @@ cbjack_xrun_callback(void * arg)
{
cubeb * ctx = (cubeb *)arg;
float delay = api_jack_get_xrun_delayed_usecs(ctx->jack_client);
float delay = WRAP(jack_get_xrun_delayed_usecs)(ctx->jack_client);
float fragments = ceilf(((delay / 1000000.0) * ctx->jack_sample_rate) /
ctx->jack_buffer_size);
@ -368,8 +375,8 @@ cbjack_graph_order_callback(void * arg)
continue;
for (i = 0; i < (int)stm->out_params.channels; ++i) {
api_jack_port_get_latency_range(stm->output_ports[i], JackPlaybackLatency,
&latency_range);
WRAP(jack_port_get_latency_range)
(stm->output_ports[i], JackPlaybackLatency, &latency_range);
port_latency = latency_range.max;
if (port_latency > max_latency)
max_latency = port_latency;
@ -411,13 +418,13 @@ cbjack_process(jack_nframes_t nframes, void * arg)
// get jack output buffers
for (i = 0; i < (int)stm->out_params.channels; i++)
bufs_out[i] =
(float *)api_jack_port_get_buffer(stm->output_ports[i], nframes);
(float *)WRAP(jack_port_get_buffer)(stm->output_ports[i], nframes);
}
if (stm->devs & IN_ONLY) {
// get jack input buffers
for (i = 0; i < (int)stm->in_params.channels; i++)
bufs_in[i] =
(float *)api_jack_port_get_buffer(stm->input_ports[i], nframes);
(float *)WRAP(jack_port_get_buffer)(stm->input_ports[i], nframes);
}
if (stm->pause) {
// paused, play silence on output
@ -684,8 +691,8 @@ jack_init(cubeb ** context, char const * context_name)
return CUBEB_ERROR;
}
api_jack_set_error_function(silent_jack_error_callback);
api_jack_set_info_function(silent_jack_error_callback);
WRAP(jack_set_error_function)(silent_jack_error_callback);
WRAP(jack_set_info_function)(silent_jack_error_callback);
ctx->ops = &cbjack_ops;
@ -699,7 +706,7 @@ jack_init(cubeb ** context, char const * context_name)
jack_client_name = context_name;
ctx->jack_client =
api_jack_client_open(jack_client_name, JackNoStartServer, NULL);
WRAP(jack_client_open)(jack_client_name, JackNoStartServer, NULL);
if (ctx->jack_client == NULL) {
cbjack_destroy(ctx);
@ -708,17 +715,17 @@ jack_init(cubeb ** context, char const * context_name)
ctx->jack_xruns = 0;
api_jack_set_process_callback(ctx->jack_client, cbjack_process, ctx);
api_jack_set_xrun_callback(ctx->jack_client, cbjack_xrun_callback, ctx);
api_jack_set_graph_order_callback(ctx->jack_client,
cbjack_graph_order_callback, ctx);
WRAP(jack_set_process_callback)(ctx->jack_client, cbjack_process, ctx);
WRAP(jack_set_xrun_callback)(ctx->jack_client, cbjack_xrun_callback, ctx);
WRAP(jack_set_graph_order_callback)
(ctx->jack_client, cbjack_graph_order_callback, ctx);
if (api_jack_activate(ctx->jack_client)) {
if (WRAP(jack_activate)(ctx->jack_client)) {
cbjack_destroy(ctx);
return CUBEB_ERROR;
}
ctx->jack_sample_rate = api_jack_get_sample_rate(ctx->jack_client);
ctx->jack_sample_rate = WRAP(jack_get_sample_rate)(ctx->jack_client);
ctx->jack_latency = 128 * 1000 / ctx->jack_sample_rate;
ctx->active = true;
@ -760,16 +767,16 @@ cbjack_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
{
if (!ctx->jack_client) {
jack_client_t * testclient =
api_jack_client_open("test-samplerate", JackNoStartServer, NULL);
WRAP(jack_client_open)("test-samplerate", JackNoStartServer, NULL);
if (!testclient) {
return CUBEB_ERROR;
}
*rate = api_jack_get_sample_rate(testclient);
api_jack_client_close(testclient);
*rate = WRAP(jack_get_sample_rate)(testclient);
WRAP(jack_client_close)(testclient);
} else {
*rate = api_jack_get_sample_rate(ctx->jack_client);
*rate = WRAP(jack_get_sample_rate)(ctx->jack_client);
}
return CUBEB_OK;
}
@ -780,7 +787,7 @@ cbjack_destroy(cubeb * context)
context->active = false;
if (context->jack_client != NULL)
api_jack_client_close(context->jack_client);
WRAP(jack_client_close)(context->jack_client);
if (context->libjack)
dlclose(context->libjack);
@ -813,7 +820,7 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream,
cubeb_state_callback state_callback, void * user_ptr)
{
int stream_actual_rate = 0;
int jack_rate = api_jack_get_sample_rate(context->jack_client);
int jack_rate = WRAP(jack_get_sample_rate)(context->jack_client);
if (output_stream_params &&
(output_stream_params->format != CUBEB_SAMPLE_FLOAT32NE &&
@ -905,7 +912,7 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream,
stm->state_callback = state_callback;
stm->position = 0;
stm->volume = 1.0f;
context->jack_buffer_size = api_jack_get_buffer_size(context->jack_client);
context->jack_buffer_size = WRAP(jack_get_buffer_size)(context->jack_client);
context->fragment_size = context->jack_buffer_size;
if (stm->devs == NONE) {
@ -939,9 +946,9 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream,
for (unsigned int c = 0; c < stm->out_params.channels; c++) {
char portname[256];
snprintf(portname, 255, "%s_out_%d", stm->stream_name, c);
stm->output_ports[c] =
api_jack_port_register(stm->context->jack_client, portname,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
stm->output_ports[c] = WRAP(jack_port_register)(
stm->context->jack_client, portname, JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (!(output_stream_params->prefs &
CUBEB_STREAM_PREF_JACK_NO_AUTO_CONNECT)) {
if (cbjack_connect_ports(stm, CBJACK_CP_OPTIONS_SKIP_INPUT) !=
@ -959,8 +966,8 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream,
char portname[256];
snprintf(portname, 255, "%s_in_%d", stm->stream_name, c);
stm->input_ports[c] =
api_jack_port_register(stm->context->jack_client, portname,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
WRAP(jack_port_register)(stm->context->jack_client, portname,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
if (!(input_stream_params->prefs &
CUBEB_STREAM_PREF_JACK_NO_AUTO_CONNECT)) {
if (cbjack_connect_ports(stm, CBJACK_CP_OPTIONS_SKIP_OUTPUT) !=
@ -991,8 +998,8 @@ cbjack_stream_destroy(cubeb_stream * stream)
if (stream->devs == DUPLEX || stream->devs == OUT_ONLY) {
for (unsigned int c = 0; c < stream->out_params.channels; c++) {
if (stream->output_ports[c]) {
api_jack_port_unregister(stream->context->jack_client,
stream->output_ports[c]);
WRAP(jack_port_unregister)
(stream->context->jack_client, stream->output_ports[c]);
stream->output_ports[c] = NULL;
}
}
@ -1001,8 +1008,8 @@ cbjack_stream_destroy(cubeb_stream * stream)
if (stream->devs == DUPLEX || stream->devs == IN_ONLY) {
for (unsigned int c = 0; c < stream->in_params.channels; c++) {
if (stream->input_ports[c]) {
api_jack_port_unregister(stream->context->jack_client,
stream->input_ports[c]);
WRAP(jack_port_unregister)
(stream->context->jack_client, stream->input_ports[c]);
stream->input_ports[c] = NULL;
}
}

Просмотреть файл

@ -410,9 +410,8 @@ sum2(TYPE_SAMPLE * out, uint32_t stride_out, const TYPE_SAMPLE * in1,
TYPE_COEFF coeff2, F && operand, uint32_t frames)
{
static_assert(
std::is_same<TYPE_COEFF,
typename std::result_of<F(TYPE_COEFF)>::type>::value,
"function must return the same type as used by matrix_coeff");
std::is_same<TYPE_COEFF, decltype(operand(coeff1))>::value,
"function must return the same type as used by coeff1 and coeff2");
for (uint32_t i = 0; i < frames; i++) {
*out = operand(coeff1 * *in1 + coeff2 * *in2);
out += stride_out;
@ -426,10 +425,8 @@ void
copy(TYPE_SAMPLE * out, uint32_t stride_out, const TYPE_SAMPLE * in,
uint32_t stride_in, TYPE_COEFF coeff, F && operand, uint32_t frames)
{
static_assert(
std::is_same<TYPE_COEFF,
typename std::result_of<F(TYPE_COEFF)>::type>::value,
"function must return the same type as used by matrix_coeff");
static_assert(std::is_same<TYPE_COEFF, decltype(operand(coeff))>::value,
"function must return the same type as used by coeff");
for (uint32_t i = 0; i < frames; i++) {
*out = operand(coeff * *in);
out += stride_out;
@ -443,8 +440,7 @@ rematrix(const MixerContext * s, TYPE * aOut, const TYPE * aIn,
const TYPE_COEFF (&matrix_coeff)[COLS][COLS], F && aF, uint32_t frames)
{
static_assert(
std::is_same<TYPE_COEFF,
typename std::result_of<F(TYPE_COEFF)>::type>::value,
std::is_same<TYPE_COEFF, decltype(aF(matrix_coeff[0][0]))>::value,
"function must return the same type as used by matrix_coeff");
for (uint32_t out_i = 0; out_i < s->_out_ch_count; out_i++) {

Просмотреть файл

@ -96,6 +96,7 @@ struct oss_stream {
oss_devnode_t name;
int fd;
void * buf;
unsigned int bufframes;
struct stream_info {
int channels;
@ -126,9 +127,6 @@ struct cubeb_stream {
cubeb_data_callback data_cb;
cubeb_state_callback state_cb;
uint64_t frames_written /* (m) */;
unsigned int nfr; /* Number of frames allocated */
unsigned int nfrags;
unsigned int bufframes;
};
static char const *
@ -786,40 +784,72 @@ oss_put_play_frames(cubeb_stream * s, unsigned int nframes)
}
static int
oss_wait_playfd_for_space(cubeb_stream * s)
oss_wait_fds_for_space(cubeb_stream * s, long * nfrp)
{
struct pollfd pfd;
audio_buf_info bi;
struct pollfd pfds[2];
long nfr, tnfr;
int i;
pfd.events = POLLOUT | POLLHUP;
pfd.revents = 0;
pfd.fd = s->play.fd;
assert(s->play.fd != -1 || s->record.fd != -1);
pfds[0].events = POLLOUT | POLLHUP;
pfds[0].revents = 0;
pfds[0].fd = s->play.fd;
pfds[1].events = POLLIN | POLLHUP;
pfds[1].revents = 0;
pfds[1].fd = s->record.fd;
if (poll(&pfd, 1, 2000) == -1) {
retry:
nfr = LONG_MAX;
if (poll(pfds, 2, 1000) == -1) {
return CUBEB_ERROR;
}
if (pfd.revents & POLLHUP) {
return CUBEB_ERROR;
}
return 0;
}
static int
oss_wait_recfd_for_space(cubeb_stream * s)
{
struct pollfd pfd;
pfd.events = POLLIN | POLLHUP;
pfd.revents = 0;
pfd.fd = s->record.fd;
if (poll(&pfd, 1, 2000) == -1) {
return CUBEB_ERROR;
for (i = 0; i < 2; i++) {
if (pfds[i].revents & POLLHUP) {
return CUBEB_ERROR;
}
}
if (pfd.revents & POLLHUP) {
return CUBEB_ERROR;
if (s->play.fd != -1) {
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) {
return CUBEB_STATE_ERROR;
}
tnfr = bi.bytes / s->play.frame_size;
if (tnfr <= 0) {
/* too little space - stop polling record, if any */
pfds[0].fd = s->play.fd;
pfds[1].fd = -1;
goto retry;
} else if (tnfr > (long)s->play.bufframes) {
/* too many frames available - limit */
tnfr = (long)s->play.bufframes;
}
if (nfr > tnfr) {
nfr = tnfr;
}
}
if (s->record.fd != -1) {
if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi) == -1) {
return CUBEB_STATE_ERROR;
}
tnfr = bi.bytes / s->record.frame_size;
if (tnfr <= 0) {
/* too little space - stop polling playback, if any */
pfds[0].fd = -1;
pfds[1].fd = s->record.fd;
goto retry;
} else if (tnfr > (long)s->record.bufframes) {
/* too many frames available - limit */
tnfr = (long)s->record.bufframes;
}
if (nfr > tnfr) {
nfr = tnfr;
}
}
*nfrp = nfr;
return 0;
}
@ -840,7 +870,7 @@ oss_audio_loop(cubeb_stream * s, cubeb_state * new_state)
}
trig |= PCM_ENABLE_INPUT;
memset(s->record.buf, 0, s->bufframes * s->record.frame_size);
memset(s->record.buf, 0, s->record.bufframes * s->record.frame_size);
if (ioctl(s->record.fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1) {
LOG("Error %d occured when setting trigger on record fd", errno);
@ -877,6 +907,7 @@ oss_audio_loop(cubeb_stream * s, cubeb_state * new_state)
oss_linear32_to_float(s->record.buf, s->record.info.channels * nfr);
}
}
got = s->data_cb(s, s->user_ptr, s->record.buf, s->play.buf, nfr);
if (got == CUBEB_ERROR) {
state = CUBEB_STATE_ERROR;
@ -920,44 +951,9 @@ oss_audio_loop(cubeb_stream * s, cubeb_state * new_state)
}
}
nfr = s->bufframes;
if (record_on) {
long mfr;
if (oss_wait_recfd_for_space(s) != 0) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
audio_buf_info bi;
if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi) == -1) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
mfr = (bi.fragsize * bi.fragments) / s->record.frame_size;
if (nfr > mfr)
nfr = mfr;
}
if (play_on) {
long mfr;
if (oss_wait_playfd_for_space(s) != 0) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
audio_buf_info bi;
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
mfr = (bi.fragsize * bi.fragments) / s->play.frame_size;
if (nfr > mfr)
nfr = mfr;
if (oss_wait_fds_for_space(s, &nfr) != 0) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
}
@ -1015,9 +1011,10 @@ static inline int
oss_calc_frag_shift(unsigned int frames, unsigned int frame_size)
{
int n = 4;
int blksize = (frames * frame_size + OSS_NFRAGS - 1) / OSS_NFRAGS;
while ((1 << n) < blksize)
int blksize = frames * frame_size;
while ((1 << n) < blksize) {
n++;
}
return n;
}
@ -1037,7 +1034,6 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
cubeb_state_callback state_callback, void * user_ptr)
{
int ret = CUBEB_OK;
unsigned int playnfr = 0, recnfr = 0;
cubeb_stream * s = NULL;
const char * defdsp;
@ -1051,7 +1047,6 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
}
s->state = CUBEB_STATE_STOPPED;
s->record.fd = s->play.fd = -1;
s->nfr = latency_frames;
if (input_device != NULL) {
strlcpy(s->record.name, input_device, sizeof(s->record.name));
} else {
@ -1064,6 +1059,8 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
}
if (input_stream_params != NULL) {
unsigned int nb_channels;
uint32_t minframes;
if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
@ -1077,13 +1074,11 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
ret = CUBEB_ERROR_INVALID_PARAMETER;
goto error;
}
if (s->record.fd == -1) {
if ((s->record.fd = open(s->record.name, O_RDONLY)) == -1) {
LOG("Audio device \"%s\" could not be opened as read-only",
s->record.name);
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
if ((s->record.fd = open(s->record.name, O_RDONLY)) == -1) {
LOG("Audio device \"%s\" could not be opened as read-only",
s->record.name);
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
if ((ret = oss_copy_params(s->record.fd, s, input_stream_params,
&s->record.info)) != CUBEB_OK) {
@ -1094,11 +1089,17 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
(input_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
s->record.frame_size =
s->record.info.channels * (s->record.info.precision / 8);
recnfr = (1 << oss_calc_frag_shift(s->nfr, s->record.frame_size)) /
s->record.frame_size;
s->record.bufframes = latency_frames;
oss_get_min_latency(context, *input_stream_params, &minframes);
if (s->record.bufframes < minframes) {
s->record.bufframes = minframes;
}
}
if (output_stream_params != NULL) {
unsigned int nb_channels;
uint32_t minframes;
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
@ -1113,13 +1114,11 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
ret = CUBEB_ERROR_INVALID_PARAMETER;
goto error;
}
if (s->play.fd == -1) {
if ((s->play.fd = open(s->play.name, O_WRONLY)) == -1) {
LOG("Audio device \"%s\" could not be opened as write-only",
s->play.name);
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
if ((s->play.fd = open(s->play.name, O_WRONLY)) == -1) {
LOG("Audio device \"%s\" could not be opened as write-only",
s->play.name);
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
if ((ret = oss_copy_params(s->play.fd, s, output_stream_params,
&s->play.info)) != CUBEB_OK) {
@ -1128,19 +1127,16 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
}
s->play.floating = (output_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
s->play.frame_size = s->play.info.channels * (s->play.info.precision / 8);
playnfr = (1 << oss_calc_frag_shift(s->nfr, s->play.frame_size)) /
s->play.frame_size;
s->play.bufframes = latency_frames;
oss_get_min_latency(context, *output_stream_params, &minframes);
if (s->play.bufframes < minframes) {
s->play.bufframes = minframes;
}
}
/*
* Use the largest nframes among playing and recording streams to set OSS
* buffer size. After that, use the smallest allocated nframes among both
* direction to allocate our temporary buffers.
*/
s->nfr = (playnfr > recnfr) ? playnfr : recnfr;
s->nfrags = OSS_NFRAGS;
if (s->play.fd != -1) {
int frag =
oss_get_frag_params(oss_calc_frag_shift(s->nfr, s->play.frame_size));
int frag = oss_get_frag_params(
oss_calc_frag_shift(s->play.bufframes, s->play.frame_size));
if (ioctl(s->play.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
LOG("Failed to set play fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
frag);
@ -1148,13 +1144,17 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi))
LOG("Failed to get play fd's buffer info.");
else {
if (bi.fragsize / s->play.frame_size < s->nfr)
s->nfr = bi.fragsize / s->play.frame_size;
s->play.bufframes = (bi.fragsize * bi.fragstotal) / s->play.frame_size;
}
int lw = s->play.frame_size;
if (ioctl(s->play.fd, SNDCTL_DSP_LOW_WATER, &lw))
LOG("Audio device \"%s\" (play) could not set trigger threshold",
s->play.name);
}
if (s->record.fd != -1) {
int frag =
oss_get_frag_params(oss_calc_frag_shift(s->nfr, s->record.frame_size));
int frag = oss_get_frag_params(
oss_calc_frag_shift(s->record.bufframes, s->record.frame_size));
if (ioctl(s->record.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
LOG("Failed to set record fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
frag);
@ -1162,11 +1162,15 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi))
LOG("Failed to get record fd's buffer info.");
else {
if (bi.fragsize / s->record.frame_size < s->nfr)
s->nfr = bi.fragsize / s->record.frame_size;
s->record.bufframes =
(bi.fragsize * bi.fragstotal) / s->record.frame_size;
}
int lw = s->record.frame_size;
if (ioctl(s->record.fd, SNDCTL_DSP_LOW_WATER, &lw))
LOG("Audio device \"%s\" (record) could not set trigger threshold",
s->record.name);
}
s->bufframes = s->nfr * s->nfrags;
s->context = context;
s->volume = 1.0;
s->state_cb = state_callback;
@ -1188,13 +1192,14 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
s->doorbell = false;
if (s->play.fd != -1) {
if ((s->play.buf = calloc(s->bufframes, s->play.frame_size)) == NULL) {
if ((s->play.buf = calloc(s->play.bufframes, s->play.frame_size)) == NULL) {
ret = CUBEB_ERROR;
goto error;
}
}
if (s->record.fd != -1) {
if ((s->record.buf = calloc(s->bufframes, s->record.frame_size)) == NULL) {
if ((s->record.buf = calloc(s->record.bufframes, s->record.frame_size)) ==
NULL) {
ret = CUBEB_ERROR;
goto error;
}

Просмотреть файл

@ -28,7 +28,7 @@
#ifdef DISABLE_LIBSNDIO_DLOPEN
#define WRAP(x) x
#else
#define WRAP(x) cubeb_##x
#define WRAP(x) (*cubeb_##x)
#define LIBSNDIO_API_VISIT(X) \
X(sio_close) \
X(sio_eof) \

Просмотреть файл

@ -73,17 +73,6 @@
#define CUBEB_STREAM_MAX 32
#define NBUFS 4
const GUID KSDATAFORMAT_SUBTYPE_PCM = {
0x00000001,
0x0000,
0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {
0x00000003,
0x0000,
0x0010,
{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
struct cubeb_stream_item {
SLIST_ENTRY head;
cubeb_stream * stream;