mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1105901 - Update cubeb from upstream to pick up compilation fix for glibc 2.20. r=padenot
--HG-- extra : rebase_source : cb04020b3c502f51e2411b1984bb42d8423d524b
This commit is contained in:
parent
87f717717e
commit
f151c28311
@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
|
||||
|
||||
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
|
||||
|
||||
The git commit ID used was 8948986e9c8d1e1988e67d2819492a52b719b13a.
|
||||
The git commit ID used was 14d97931da6435d10aa4dcb444896af0314372f4.
|
||||
|
@ -122,8 +122,8 @@ typedef enum {
|
||||
typedef struct {
|
||||
cubeb_sample_format format; /**< Requested sample format. One of
|
||||
#cubeb_sample_format. */
|
||||
unsigned int rate; /**< Requested sample rate. Valid range is [1, 192000]. */
|
||||
unsigned int channels; /**< Requested channel count. Valid range is [1, 32]. */
|
||||
unsigned int rate; /**< Requested sample rate. Valid range is [1000, 192000]. */
|
||||
unsigned int channels; /**< Requested channel count. Valid range is [1, 8]. */
|
||||
#if defined(__ANDROID__)
|
||||
cubeb_stream_type stream_type; /**< Used to map Android audio stream types */
|
||||
#endif
|
||||
@ -148,7 +148,8 @@ enum {
|
||||
CUBEB_OK = 0, /**< Success. */
|
||||
CUBEB_ERROR = -1, /**< Unclassified error. */
|
||||
CUBEB_ERROR_INVALID_FORMAT = -2, /**< Unsupported #cubeb_stream_params requested. */
|
||||
CUBEB_ERROR_INVALID_PARAMETER = -3 /**< Invalid parameter specified. */
|
||||
CUBEB_ERROR_INVALID_PARAMETER = -3, /**< Invalid parameter specified. */
|
||||
CUBEB_ERROR_NOT_SUPPORTED = -4 /**< Optional function not implemented in current backend. */
|
||||
};
|
||||
|
||||
/** User supplied data callback.
|
||||
@ -156,7 +157,8 @@ enum {
|
||||
@param user_ptr
|
||||
@param buffer
|
||||
@param nframes
|
||||
@retval Number of frames written to buffer, which must equal nframes except at end of stream.
|
||||
@retval Number of frames written to buffer, which must equal nframes except
|
||||
at end of stream.
|
||||
@retval CUBEB_ERROR on error, in which case the data callback will stop
|
||||
and the stream will enter a shutdown state. */
|
||||
typedef long (* cubeb_data_callback)(cubeb_stream * stream,
|
||||
@ -195,6 +197,7 @@ char const * cubeb_get_backend_id(cubeb * context);
|
||||
@param max_channels The maximum number of channels.
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED
|
||||
@retval CUBEB_ERROR */
|
||||
int cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels);
|
||||
|
||||
@ -205,16 +208,20 @@ int cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels);
|
||||
@param params On some backends, the minimum achievable latency depends on
|
||||
the characteristics of the stream.
|
||||
@param latency_ms The latency value, in ms, to pass to cubeb_stream_init.
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER
|
||||
@retval CUBEB_OK */
|
||||
int cubeb_get_min_latency(cubeb * context, cubeb_stream_params params, uint32_t * latency_ms);
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_get_min_latency(cubeb * context,
|
||||
cubeb_stream_params params,
|
||||
uint32_t * latency_ms);
|
||||
|
||||
/** Get the preferred sample rate for this backend: this is hardware and platform
|
||||
dependant, and can avoid resampling, and/or trigger fastpaths.
|
||||
@param context
|
||||
@param rate The samplerate (in Hz) the current configuration prefers.
|
||||
@return CUBEB_ERROR_INVALID_PARAMETER
|
||||
@return CUBEB_OK */
|
||||
/** Get the preferred sample rate for this backend: this is hardware and
|
||||
platform dependant, and can avoid resampling, and/or trigger fastpaths.
|
||||
@param context
|
||||
@param rate The samplerate (in Hz) the current configuration prefers.
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate);
|
||||
|
||||
/** Destroy an application context.
|
||||
@ -226,16 +233,20 @@ void cubeb_destroy(cubeb * context);
|
||||
@param stream
|
||||
@param stream_name
|
||||
@param stream_params
|
||||
@param latency Approximate stream latency in milliseconds. Valid range is [1, 2000].
|
||||
@param latency Approximate stream latency in milliseconds. Valid range
|
||||
is [1, 2000].
|
||||
@param data_callback Will be called to preroll data before playback is
|
||||
started by cubeb_stream_start.
|
||||
started by cubeb_stream_start.
|
||||
@param state_callback
|
||||
@param user_ptr
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR
|
||||
@retval CUBEB_ERROR_INVALID_FORMAT */
|
||||
int cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_stream_params stream_params, unsigned int latency,
|
||||
int cubeb_stream_init(cubeb * context,
|
||||
cubeb_stream ** stream,
|
||||
char const * stream_name,
|
||||
cubeb_stream_params stream_params,
|
||||
unsigned int latency,
|
||||
cubeb_data_callback data_callback,
|
||||
cubeb_state_callback state_callback,
|
||||
void * user_ptr);
|
||||
@ -269,63 +280,60 @@ int cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position);
|
||||
@param stream
|
||||
@param latency Current approximate stream latency in frames.
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED
|
||||
@retval CUBEB_ERROR */
|
||||
int cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency);
|
||||
|
||||
/**
|
||||
* Set the volume for a stream.
|
||||
* @param stream the stream for which to adjust the volume.
|
||||
* @param volume a float between 0.0 (muted) and 1.0 (maximum volume)
|
||||
* @return CUBEB_ERROR_INVALID_PARAMETER if volume is outside [0.0; 1.0]
|
||||
* @return CUBEB_ERROR_INVALID_PARAMETER if stream is an invalid pointer
|
||||
* @return CUBEB_OK otherwise
|
||||
*/
|
||||
/** Set the volume for a stream.
|
||||
@param stream the stream for which to adjust the volume.
|
||||
@param volume a float between 0.0 (muted) and 1.0 (maximum volume)
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER volume is outside [0.0, 1.0] or
|
||||
stream is an invalid pointer
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_stream_set_volume(cubeb_stream * stream, float volume);
|
||||
|
||||
/**
|
||||
* If the stream is stereo, set the left/right panning. If the stream is mono,
|
||||
* this has no effect.
|
||||
* @param stream the stream for which to change the panning
|
||||
* @param panning a number from -1.0 to 1.0. -1.0 means that the stream is fully
|
||||
* mixed in the left channel, 1.0 means the stream is fully mixed in the right
|
||||
* channel. 0.0 is equal power in the right and left channel (default).
|
||||
* @return CUBEB_ERROR_INVALID_PARAMETER if stream is null or if panning is outside
|
||||
* the [-1.0; 1.0] range.
|
||||
* @return CUBEB_ERROR if this stream is not mono nor stereo.
|
||||
* @return CUBEB_OK otherwise.
|
||||
*/
|
||||
/** If the stream is stereo, set the left/right panning. If the stream is mono,
|
||||
this has no effect.
|
||||
@param stream the stream for which to change the panning
|
||||
@param panning a number from -1.0 to 1.0. -1.0 means that the stream is
|
||||
fully mixed in the left channel, 1.0 means the stream is fully
|
||||
mixed in the right channel. 0.0 is equal power in the right and
|
||||
left channel (default).
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER if stream is null or if panning is
|
||||
outside the [-1.0, 1.0] range.
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED
|
||||
@retval CUBEB_ERROR stream is not mono nor stereo */
|
||||
int cubeb_stream_set_panning(cubeb_stream * stream, float panning);
|
||||
|
||||
/**
|
||||
* Get the current output device for this stream.
|
||||
* @param stm the stream for which to query the current output device
|
||||
* @param device a pointer in which the current output device will be stored.
|
||||
* @return CUBEB_OK in case of success
|
||||
* @return CUBEB_ERROR_INVALID_PARAMETER if either stm, device or count are
|
||||
* invalid pointers
|
||||
*/
|
||||
/** Get the current output device for this stream.
|
||||
@param stm the stream for which to query the current output device
|
||||
@param device a pointer in which the current output device will be stored.
|
||||
@retval CUBEB_OK in case of success
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER if either stm, device or count are
|
||||
invalid pointers
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_stream_get_current_device(cubeb_stream * stm,
|
||||
cubeb_device ** const device);
|
||||
|
||||
/**
|
||||
* Destroy a cubeb_device structure.
|
||||
* @param stream the stream passed in cubeb_stream_get_current_device
|
||||
* @param devices the devices to destroy
|
||||
* @return CUBEB_OK in case of success
|
||||
* @return CUBEB_ERROR_INVALID_PARAMETER if devices is an invalid pointer
|
||||
*/
|
||||
/** Destroy a cubeb_device structure.
|
||||
@param stream the stream passed in cubeb_stream_get_current_device
|
||||
@param devices the devices to destroy
|
||||
@retval CUBEB_OK in case of success
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER if devices is an invalid pointer
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_stream_device_destroy(cubeb_stream * stream,
|
||||
cubeb_device * devices);
|
||||
|
||||
/**
|
||||
* Set a callback to be notified when the output device changes.
|
||||
* @param stream the stream for which to set the callback.
|
||||
* @param device_changed_callback a function called whenever the device has
|
||||
* changed. Passing NULL allow to unregister a function
|
||||
* @return CUBEB_ERROR_INVALID_PARAMETER if either stream or
|
||||
* device_changed_callback are invalid pointers.
|
||||
* @return CUBEB_OK
|
||||
*/
|
||||
/** Set a callback to be notified when the output device changes.
|
||||
@param stream the stream for which to set the callback.
|
||||
@param device_changed_callback a function called whenever the device has
|
||||
changed. Passing NULL allow to unregister a function
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER if either stream or
|
||||
device_changed_callback are invalid pointers.
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
|
||||
cubeb_device_changed_callback device_changed_callback);
|
||||
|
||||
|
@ -34,8 +34,8 @@ struct cubeb_ops {
|
||||
cubeb_device ** const device);
|
||||
int (* stream_device_destroy)(cubeb_stream * stream,
|
||||
cubeb_device * device);
|
||||
int (*stream_register_device_changed_callback)(cubeb_stream * stream,
|
||||
cubeb_device_changed_callback device_changed_callback);
|
||||
int (* stream_register_device_changed_callback)(cubeb_stream * stream,
|
||||
cubeb_device_changed_callback device_changed_callback);
|
||||
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
@ -129,6 +131,15 @@ cubeb_init(cubeb ** context, char const * context_name)
|
||||
|
||||
for (i = 0; i < NELEMS(init); ++i) {
|
||||
if (init[i](context, context_name) == CUBEB_OK) {
|
||||
/* Assert that the minimal API is implemented. */
|
||||
#define OK(fn) assert((* context)->ops->fn)
|
||||
OK(get_backend_id);
|
||||
OK(destroy);
|
||||
OK(stream_init);
|
||||
OK(stream_destroy);
|
||||
OK(stream_start);
|
||||
OK(stream_stop);
|
||||
OK(stream_get_position);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
}
|
||||
@ -153,6 +164,10 @@ cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!context->ops->get_max_channel_count) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return context->ops->get_max_channel_count(context, max_channels);
|
||||
}
|
||||
|
||||
@ -162,6 +177,11 @@ cubeb_get_min_latency(cubeb * context, cubeb_stream_params params, uint32_t * la
|
||||
if (!context || !latency_ms) {
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!context->ops->get_min_latency) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return context->ops->get_min_latency(context, params, latency_ms);
|
||||
}
|
||||
|
||||
@ -171,6 +191,11 @@ cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate)
|
||||
if (!context || !rate) {
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!context->ops->get_preferred_sample_rate) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return context->ops->get_preferred_sample_rate(context, rate);
|
||||
}
|
||||
|
||||
@ -256,6 +281,10 @@ cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!stream->context->ops->stream_get_latency) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return stream->context->ops->stream_get_latency(stream, latency);
|
||||
}
|
||||
|
||||
@ -266,6 +295,10 @@ cubeb_stream_set_volume(cubeb_stream * stream, float volume)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!stream->context->ops->stream_set_volume) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return stream->context->ops->stream_set_volume(stream, volume);
|
||||
}
|
||||
|
||||
@ -275,6 +308,10 @@ int cubeb_stream_set_panning(cubeb_stream * stream, float panning)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!stream->context->ops->stream_set_panning) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return stream->context->ops->stream_set_panning(stream, panning);
|
||||
}
|
||||
|
||||
@ -285,14 +322,11 @@ int cubeb_stream_get_current_device(cubeb_stream * stream,
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// If we find an implementation, call the function, it might not be available
|
||||
// on some platforms.
|
||||
if (stream->context->ops->stream_get_current_device) {
|
||||
return stream->context->ops->stream_get_current_device(stream,
|
||||
device);
|
||||
if (!stream->context->ops->stream_get_current_device) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return CUBEB_ERROR;
|
||||
return stream->context->ops->stream_get_current_device(stream, device);
|
||||
}
|
||||
|
||||
int cubeb_stream_device_destroy(cubeb_stream * stream,
|
||||
@ -302,13 +336,11 @@ int cubeb_stream_device_destroy(cubeb_stream * stream,
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// If we find an implementation, call the function, it might not be available
|
||||
// on some platforms.
|
||||
if (stream->context->ops->stream_device_destroy) {
|
||||
return stream->context->ops->stream_device_destroy(stream, device);
|
||||
if (!stream->context->ops->stream_device_destroy) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return CUBEB_ERROR;
|
||||
return stream->context->ops->stream_device_destroy(stream, device);
|
||||
}
|
||||
|
||||
int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
|
||||
@ -318,11 +350,9 @@ int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (stream->context->ops->stream_register_device_changed_callback) {
|
||||
return stream->context->ops->
|
||||
stream_register_device_changed_callback(stream,
|
||||
device_changed_callback);
|
||||
if (!stream->context->ops->stream_register_device_changed_callback) {
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return CUBEB_ERROR;
|
||||
return stream->context->ops->stream_register_device_changed_callback(stream, device_changed_callback);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#undef NDEBUG
|
||||
#define _DEFAULT_SOURCE
|
||||
#define _BSD_SOURCE
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <pthread.h>
|
||||
@ -920,7 +921,7 @@ alsa_stream_destroy(cubeb_stream * stm)
|
||||
static int
|
||||
alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
{
|
||||
int rv;
|
||||
int r;
|
||||
cubeb_stream * stm;
|
||||
snd_pcm_hw_params_t* hw_params;
|
||||
cubeb_stream_params params;
|
||||
@ -932,18 +933,18 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
|
||||
assert(ctx);
|
||||
|
||||
rv = alsa_stream_init(ctx, &stm, "", params, 100, NULL, NULL, NULL);
|
||||
if (rv != CUBEB_OK) {
|
||||
r = alsa_stream_init(ctx, &stm, "", params, 100, NULL, NULL, NULL);
|
||||
if (r != CUBEB_OK) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
rv = snd_pcm_hw_params_any(stm->pcm, hw_params);
|
||||
if (rv < 0) {
|
||||
r = snd_pcm_hw_params_any(stm->pcm, hw_params);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
rv = snd_pcm_hw_params_get_channels_max(hw_params, max_channels);
|
||||
if (rv < 0) {
|
||||
r = snd_pcm_hw_params_get_channels_max(hw_params, max_channels);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
@ -954,7 +955,7 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
|
||||
static int
|
||||
alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) {
|
||||
int rv, dir;
|
||||
int r, dir;
|
||||
snd_pcm_t * pcm;
|
||||
snd_pcm_hw_params_t * hw_params;
|
||||
|
||||
@ -962,19 +963,19 @@ 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. */
|
||||
rv = snd_pcm_open(&pcm, "", SND_PCM_STREAM_PLAYBACK | SND_PCM_NO_AUTO_RESAMPLE, 0);
|
||||
if (rv < 0) {
|
||||
r = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK | SND_PCM_NO_AUTO_RESAMPLE, 0);
|
||||
if (r < 0) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
rv = snd_pcm_hw_params_any(pcm, hw_params);
|
||||
if (rv < 0) {
|
||||
r = snd_pcm_hw_params_any(pcm, hw_params);
|
||||
if (r < 0) {
|
||||
snd_pcm_close(pcm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
rv = snd_pcm_hw_params_get_rate(hw_params, rate, &dir);
|
||||
if (rv >= 0) {
|
||||
r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir);
|
||||
if (r >= 0) {
|
||||
/* There is a default rate: use it. */
|
||||
snd_pcm_close(pcm);
|
||||
return CUBEB_OK;
|
||||
@ -983,8 +984,8 @@ alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) {
|
||||
/* Use a common rate, alsa may adjust it based on hw/etc. capabilities. */
|
||||
*rate = 44100;
|
||||
|
||||
rv = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL);
|
||||
if (rv < 0) {
|
||||
r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL);
|
||||
if (r < 0) {
|
||||
snd_pcm_close(pcm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
@ -998,7 +999,7 @@ static int
|
||||
alsa_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latency_ms)
|
||||
{
|
||||
/* This is found to be an acceptable minimum, even on a super low-end
|
||||
* machine. */
|
||||
* machine. */
|
||||
*latency_ms = 40;
|
||||
|
||||
return CUBEB_OK;
|
||||
@ -1109,13 +1110,6 @@ alsa_stream_set_volume(cubeb_stream * stm, float volume)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
alsa_stream_set_panning(cubeb_stream * stream, float panning)
|
||||
{
|
||||
assert(0 && "not implemented");
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const alsa_ops = {
|
||||
.init = alsa_init,
|
||||
.get_backend_id = alsa_get_backend_id,
|
||||
@ -1130,7 +1124,7 @@ static struct cubeb_ops const alsa_ops = {
|
||||
.stream_get_position = alsa_stream_get_position,
|
||||
.stream_get_latency = alsa_stream_get_latency,
|
||||
.stream_set_volume = alsa_stream_set_volume,
|
||||
.stream_set_panning = alsa_stream_set_panning,
|
||||
.stream_set_panning = NULL,
|
||||
.stream_get_current_device = NULL,
|
||||
.stream_device_destroy = NULL,
|
||||
.stream_register_device_changed_callback = NULL
|
||||
|
@ -35,14 +35,14 @@
|
||||
* call dlsym to get the symbol |mangled_name|, handle the error and store the
|
||||
* pointer in |pointer|. Because depending on Android version, we want different
|
||||
* symbols, not finding a symbol is not an error. */
|
||||
#define DLSYM_DLERROR(mangled_name, pointer, lib) \
|
||||
do { \
|
||||
pointer = dlsym(lib, mangled_name); \
|
||||
if (!pointer) { \
|
||||
#define DLSYM_DLERROR(mangled_name, pointer, lib) \
|
||||
do { \
|
||||
pointer = dlsym(lib, mangled_name); \
|
||||
if (!pointer) { \
|
||||
ALOG("error while loading %stm: %stm\n", mangled_name, dlerror()); \
|
||||
} else { \
|
||||
ALOG("%stm: OK", mangled_name); \
|
||||
} \
|
||||
} else { \
|
||||
ALOG("%stm: OK", mangled_name); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
static struct cubeb_ops const audiotrack_ops;
|
||||
@ -50,28 +50,28 @@ void audiotrack_destroy(cubeb * context);
|
||||
void audiotrack_stream_destroy(cubeb_stream * stream);
|
||||
|
||||
struct AudioTrack {
|
||||
/* only available on ICS and later. The second int paramter is in fact of type audio_stream_type_t. */
|
||||
/* only available on ICS and later. The second int paramter is in fact of type audio_stream_type_t. */
|
||||
/* static */ status_t (*get_min_frame_count)(int* frame_count, int stream_type, uint32_t rate);
|
||||
/* if we have a recent ctor, but can't find the above symbol, we
|
||||
* can get the minimum frame count with this signature, and we are
|
||||
* running gingerbread. */
|
||||
/* if we have a recent ctor, but can't find the above symbol, we
|
||||
* can get the minimum frame count with this signature, and we are
|
||||
* running gingerbread. */
|
||||
/* static */ status_t (*get_min_frame_count_gingerbread)(int* frame_count, int stream_type, uint32_t rate);
|
||||
/* if this symbol is not availble, and the next one is, we know
|
||||
* we are on a Froyo (Android 2.2) device. */
|
||||
void* (*ctor)(void* instance, int, unsigned int, int, int, int, unsigned int, void (*)(int, void*, void*), void*, int, int);
|
||||
void* (*ctor_froyo)(void* instance, int, unsigned int, int, int, int, unsigned int, void (*)(int, void*, void*), void*, int);
|
||||
void* (*dtor)(void* instance);
|
||||
void (*start)(void* instance);
|
||||
void (*pause)(void* instance);
|
||||
uint32_t (*latency)(void* instance);
|
||||
status_t (*check)(void* instance);
|
||||
status_t (*get_position)(void* instance, uint32_t* position);
|
||||
/* only used on froyo. */
|
||||
/* if this symbol is not availble, and the next one is, we know
|
||||
* we are on a Froyo (Android 2.2) device. */
|
||||
void* (*ctor)(void* instance, int, unsigned int, int, int, int, unsigned int, void (*)(int, void*, void*), void*, int, int);
|
||||
void* (*ctor_froyo)(void* instance, int, unsigned int, int, int, int, unsigned int, void (*)(int, void*, void*), void*, int);
|
||||
void* (*dtor)(void* instance);
|
||||
void (*start)(void* instance);
|
||||
void (*pause)(void* instance);
|
||||
uint32_t (*latency)(void* instance);
|
||||
status_t (*check)(void* instance);
|
||||
status_t (*get_position)(void* instance, uint32_t* position);
|
||||
/* only used on froyo. */
|
||||
/* static */ int (*get_output_frame_count)(int* frame_count, int stream);
|
||||
/* static */ int (*get_output_latency)(uint32_t* latency, int stream);
|
||||
/* static */ int (*get_output_samplingrate)(int* samplerate, int stream);
|
||||
status_t (*set_marker_position)(void* instance, unsigned int);
|
||||
status_t (*set_volume)(void* instance, float left, float right);
|
||||
status_t (*set_marker_position)(void* instance, unsigned int);
|
||||
status_t (*set_volume)(void* instance, float left, float right);
|
||||
};
|
||||
|
||||
struct cubeb {
|
||||
@ -97,44 +97,44 @@ audiotrack_refill(int event, void* user, void* info)
|
||||
{
|
||||
cubeb_stream * stream = user;
|
||||
switch (event) {
|
||||
case EVENT_MORE_DATA: {
|
||||
long got = 0;
|
||||
struct Buffer * b = (struct Buffer*)info;
|
||||
case EVENT_MORE_DATA: {
|
||||
long got = 0;
|
||||
struct Buffer * b = (struct Buffer*)info;
|
||||
|
||||
if (stream->draining) {
|
||||
return;
|
||||
}
|
||||
|
||||
got = stream->data_callback(stream, stream->user_ptr, b->raw, b->frameCount);
|
||||
|
||||
stream->written += got;
|
||||
|
||||
if (got != (long)b->frameCount) {
|
||||
uint32_t p;
|
||||
stream->draining = 1;
|
||||
/* set a marker so we are notified when the are done draining, that is,
|
||||
* when every frame has been played by android. */
|
||||
stream->context->klass.set_marker_position(stream->instance, stream->written);
|
||||
}
|
||||
|
||||
break;
|
||||
if (stream->draining) {
|
||||
return;
|
||||
}
|
||||
case EVENT_UNDERRUN:
|
||||
ALOG("underrun in cubeb backend.");
|
||||
break;
|
||||
case EVENT_LOOP_END:
|
||||
assert(0 && "We don't support the loop feature of audiotrack.");
|
||||
break;
|
||||
case EVENT_MARKER:
|
||||
assert(stream->draining);
|
||||
stream->state_callback(stream, stream->user_ptr, CUBEB_STATE_DRAINED);
|
||||
break;
|
||||
case EVENT_NEW_POS:
|
||||
assert(0 && "We don't support the setPositionUpdatePeriod feature of audiotrack.");
|
||||
break;
|
||||
case EVENT_BUFFER_END:
|
||||
assert(0 && "Should not happen.");
|
||||
break;
|
||||
|
||||
got = stream->data_callback(stream, stream->user_ptr, b->raw, b->frameCount);
|
||||
|
||||
stream->written += got;
|
||||
|
||||
if (got != (long)b->frameCount) {
|
||||
uint32_t p;
|
||||
stream->draining = 1;
|
||||
/* set a marker so we are notified when the are done draining, that is,
|
||||
* when every frame has been played by android. */
|
||||
stream->context->klass.set_marker_position(stream->instance, stream->written);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case EVENT_UNDERRUN:
|
||||
ALOG("underrun in cubeb backend.");
|
||||
break;
|
||||
case EVENT_LOOP_END:
|
||||
assert(0 && "We don't support the loop feature of audiotrack.");
|
||||
break;
|
||||
case EVENT_MARKER:
|
||||
assert(stream->draining);
|
||||
stream->state_callback(stream, stream->user_ptr, CUBEB_STATE_DRAINED);
|
||||
break;
|
||||
case EVENT_NEW_POS:
|
||||
assert(0 && "We don't support the setPositionUpdatePeriod feature of audiotrack.");
|
||||
break;
|
||||
case EVENT_BUFFER_END:
|
||||
assert(0 && "Should not happen.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,12 +256,12 @@ audiotrack_init(cubeb ** context, char const * context_name)
|
||||
/* check that we have a combination of symbol that makes sense */
|
||||
c = &ctx->klass;
|
||||
if(!((c->ctor || c->ctor_froyo) && /* at least on ctor. */
|
||||
c->dtor && c->latency && c->check &&
|
||||
/* at least one way to get the minimum frame count to request. */
|
||||
((c->get_output_frame_count && c->get_output_latency && c->get_output_samplingrate) ||
|
||||
c->get_min_frame_count ||
|
||||
c->get_min_frame_count_gingerbread) &&
|
||||
c->start && c->pause && c->get_position && c->set_marker_position)) {
|
||||
c->dtor && c->latency && c->check &&
|
||||
/* at least one way to get the minimum frame count to request. */
|
||||
((c->get_output_frame_count && c->get_output_latency && c->get_output_samplingrate) ||
|
||||
c->get_min_frame_count ||
|
||||
c->get_min_frame_count_gingerbread) &&
|
||||
c->start && c->pause && c->get_position && c->set_marker_position)) {
|
||||
ALOG("Could not find all the symbols we need.");
|
||||
audiotrack_destroy(ctx);
|
||||
return CUBEB_ERROR;
|
||||
@ -286,7 +286,7 @@ audiotrack_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
assert(ctx && max_channels);
|
||||
|
||||
/* The android mixer handles up to two channels, see
|
||||
http://androidxref.com/4.2.2_r1/xref/frameworks/av/services/audioflinger/AudioFlinger.h#67 */
|
||||
http://androidxref.com/4.2.2_r1/xref/frameworks/av/services/audioflinger/AudioFlinger.h#67 */
|
||||
*max_channels = 2;
|
||||
|
||||
return CUBEB_OK;
|
||||
@ -297,10 +297,10 @@ audiotrack_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * l
|
||||
{
|
||||
/* We always use the lowest latency possible when using this backend (see
|
||||
* audiotrack_stream_init), so this value is not going to be used. */
|
||||
int rv;
|
||||
int r;
|
||||
|
||||
rv = audiotrack_get_min_frame_count(ctx, ¶ms, (int *)latency_ms);
|
||||
if (rv != CUBEB_OK) {
|
||||
r = audiotrack_get_min_frame_count(ctx, ¶ms, (int *)latency_ms);
|
||||
if (r != CUBEB_OK) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
@ -313,11 +313,11 @@ audiotrack_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * l
|
||||
static int
|
||||
audiotrack_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
||||
{
|
||||
status_t rv;
|
||||
status_t r;
|
||||
|
||||
rv = ctx->klass.get_output_samplingrate((int32_t *)rate, 3 /* MUSIC */);
|
||||
r = ctx->klass.get_output_samplingrate((int32_t *)rate, 3 /* MUSIC */);
|
||||
|
||||
return rv == 0 ? CUBEB_OK : CUBEB_ERROR;
|
||||
return r == 0 ? CUBEB_OK : CUBEB_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
@ -483,13 +483,6 @@ audiotrack_stream_set_volume(cubeb_stream * stream, float volume)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
audiotrack_stream_set_panning(cubeb_stream * stream, float panning)
|
||||
{
|
||||
assert(false && "not implemented.");
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const audiotrack_ops = {
|
||||
.init = audiotrack_init,
|
||||
.get_backend_id = audiotrack_get_backend_id,
|
||||
@ -504,7 +497,7 @@ static struct cubeb_ops const audiotrack_ops = {
|
||||
.stream_get_position = audiotrack_stream_get_position,
|
||||
.stream_get_latency = audiotrack_stream_get_latency,
|
||||
.stream_set_volume = audiotrack_stream_set_volume,
|
||||
.stream_set_panning = audiotrack_stream_set_panning,
|
||||
.stream_set_panning = NULL,
|
||||
.stream_get_current_device = NULL,
|
||||
.stream_device_destroy = NULL,
|
||||
.stream_register_device_changed_callback = NULL
|
||||
|
@ -223,15 +223,15 @@ audiounit_property_listener_callback(AudioObjectID id, UInt32 address_count,
|
||||
|
||||
for (UInt32 i = 0; i < address_count; i++) {
|
||||
switch(addresses[i].mSelector) {
|
||||
case kAudioHardwarePropertyDefaultOutputDevice:
|
||||
/* fall through */
|
||||
case kAudioDevicePropertyDataSource:
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
if (stm->device_changed_callback) {
|
||||
stm->device_changed_callback(stm->user_ptr);
|
||||
}
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
break;
|
||||
case kAudioHardwarePropertyDefaultOutputDevice:
|
||||
/* fall through */
|
||||
case kAudioDevicePropertyDataSource:
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
if (stm->device_changed_callback) {
|
||||
stm->device_changed_callback(stm->user_ptr);
|
||||
}
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,7 +494,7 @@ audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stre
|
||||
case CUBEB_SAMPLE_S16BE:
|
||||
ss.mBitsPerChannel = 16;
|
||||
ss.mFormatFlags |= kAudioFormatFlagIsSignedInteger |
|
||||
kAudioFormatFlagIsBigEndian;
|
||||
kAudioFormatFlagIsBigEndian;
|
||||
break;
|
||||
case CUBEB_SAMPLE_FLOAT32LE:
|
||||
ss.mBitsPerChannel = 32;
|
||||
@ -503,7 +503,7 @@ audiounit_stream_init(cubeb * context, cubeb_stream ** stream, char const * stre
|
||||
case CUBEB_SAMPLE_FLOAT32BE:
|
||||
ss.mBitsPerChannel = 32;
|
||||
ss.mFormatFlags |= kAudioFormatFlagIsFloat |
|
||||
kAudioFormatFlagIsBigEndian;
|
||||
kAudioFormatFlagIsBigEndian;
|
||||
break;
|
||||
default:
|
||||
return CUBEB_ERROR_INVALID_FORMAT;
|
||||
@ -911,7 +911,7 @@ int audiounit_stream_device_destroy(cubeb_stream * stream,
|
||||
}
|
||||
|
||||
int audiounit_stream_register_device_changed_callback(cubeb_stream * stream,
|
||||
cubeb_device_changed_callback device_changed_callback)
|
||||
cubeb_device_changed_callback device_changed_callback)
|
||||
{
|
||||
pthread_mutex_lock(&stream->mutex);
|
||||
stream->device_changed_callback = device_changed_callback;
|
||||
|
@ -78,15 +78,15 @@ play_callback(SLPlayItf caller, void * user_ptr, SLuint32 event)
|
||||
cubeb_stream * stm = user_ptr;
|
||||
assert(stm);
|
||||
switch (event) {
|
||||
case SL_PLAYEVENT_HEADATMARKER:
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
assert(stm->draining);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
|
||||
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case SL_PLAYEVENT_HEADATMARKER:
|
||||
pthread_mutex_lock(&stm->mutex);
|
||||
assert(stm->draining);
|
||||
pthread_mutex_unlock(&stm->mutex);
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
|
||||
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ bufferqueue_callback(SLBufferQueueItf caller, void * user_ptr)
|
||||
|
||||
if (!draining) {
|
||||
written = cubeb_resampler_fill(stm->resampler, buf,
|
||||
stm->queuebuf_len / stm->framesize);
|
||||
stm->queuebuf_len / stm->framesize);
|
||||
if (written < 0 || written * stm->framesize > stm->queuebuf_len) {
|
||||
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
|
||||
return;
|
||||
@ -151,22 +151,22 @@ static SLuint32
|
||||
convert_stream_type_to_sl_stream(cubeb_stream_type stream_type)
|
||||
{
|
||||
switch(stream_type) {
|
||||
case CUBEB_STREAM_TYPE_SYSTEM:
|
||||
return SL_ANDROID_STREAM_SYSTEM;
|
||||
case CUBEB_STREAM_TYPE_MUSIC:
|
||||
return SL_ANDROID_STREAM_MEDIA;
|
||||
case CUBEB_STREAM_TYPE_NOTIFICATION:
|
||||
return SL_ANDROID_STREAM_NOTIFICATION;
|
||||
case CUBEB_STREAM_TYPE_ALARM:
|
||||
return SL_ANDROID_STREAM_ALARM;
|
||||
case CUBEB_STREAM_TYPE_VOICE_CALL:
|
||||
return SL_ANDROID_STREAM_VOICE;
|
||||
case CUBEB_STREAM_TYPE_RING:
|
||||
return SL_ANDROID_STREAM_RING;
|
||||
case CUBEB_STREAM_TYPE_SYSTEM_ENFORCED:
|
||||
return SL_ANDROID_STREAM_SYSTEM_ENFORCED;
|
||||
default:
|
||||
return 0xFFFFFFFF;
|
||||
case CUBEB_STREAM_TYPE_SYSTEM:
|
||||
return SL_ANDROID_STREAM_SYSTEM;
|
||||
case CUBEB_STREAM_TYPE_MUSIC:
|
||||
return SL_ANDROID_STREAM_MEDIA;
|
||||
case CUBEB_STREAM_TYPE_NOTIFICATION:
|
||||
return SL_ANDROID_STREAM_NOTIFICATION;
|
||||
case CUBEB_STREAM_TYPE_ALARM:
|
||||
return SL_ANDROID_STREAM_ALARM;
|
||||
case CUBEB_STREAM_TYPE_VOICE_CALL:
|
||||
return SL_ANDROID_STREAM_VOICE;
|
||||
case CUBEB_STREAM_TYPE_RING:
|
||||
return SL_ANDROID_STREAM_RING;
|
||||
case CUBEB_STREAM_TYPE_SYSTEM_ENFORCED:
|
||||
return SL_ANDROID_STREAM_SYSTEM_ENFORCED;
|
||||
default:
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -317,7 +317,7 @@ opensl_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
|
||||
{
|
||||
assert(ctx && max_channels);
|
||||
/* The android mixer handles up to two channels, see
|
||||
http://androidxref.com/4.2.2_r1/xref/frameworks/av/services/audioflinger/AudioFlinger.h#67 */
|
||||
http://androidxref.com/4.2.2_r1/xref/frameworks/av/services/audioflinger/AudioFlinger.h#67 */
|
||||
*max_channels = 2;
|
||||
|
||||
return CUBEB_OK;
|
||||
@ -329,7 +329,7 @@ opensl_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
||||
/* https://android.googlesource.com/platform/ndk.git/+/master/docs/opensles/index.html
|
||||
* We don't want to deal with JNI here (and we don't have Java on b2g anyways),
|
||||
* so we just dlopen the library and get the two symbols we need. */
|
||||
int rv;
|
||||
int r;
|
||||
void * libmedia;
|
||||
uint32_t (*get_primary_output_samplingrate)();
|
||||
uint32_t (*get_output_samplingrate)(int * samplingRate, int streamType);
|
||||
@ -364,8 +364,8 @@ opensl_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
||||
*rate = get_primary_output_samplingrate();
|
||||
} else {
|
||||
/* We don't really know about the type, here, so we just pass music. */
|
||||
rv = get_output_samplingrate((int *) rate, AUDIO_STREAM_TYPE_MUSIC);
|
||||
if (rv) {
|
||||
r = get_output_samplingrate((int *) rate, AUDIO_STREAM_TYPE_MUSIC);
|
||||
if (r) {
|
||||
dlclose(libmedia);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
@ -391,16 +391,16 @@ opensl_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * laten
|
||||
* We don't want to deal with JNI here (and we don't have Java on b2g anyways),
|
||||
* so we just dlopen the library and get the two symbols we need. */
|
||||
|
||||
int rv;
|
||||
int r;
|
||||
void * libmedia;
|
||||
size_t (*get_primary_output_frame_count)(void);
|
||||
int (*get_output_frame_count)(size_t * frameCount, int streamType);
|
||||
uint32_t primary_sampling_rate;
|
||||
size_t primary_buffer_size;
|
||||
|
||||
rv = opensl_get_preferred_sample_rate(ctx, &primary_sampling_rate);
|
||||
r = opensl_get_preferred_sample_rate(ctx, &primary_sampling_rate);
|
||||
|
||||
if (rv) {
|
||||
if (r) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
@ -458,9 +458,9 @@ static void opensl_stream_destroy(cubeb_stream * stm);
|
||||
|
||||
static int
|
||||
opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_stream_params stream_params, unsigned int latency,
|
||||
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
|
||||
void * user_ptr)
|
||||
cubeb_stream_params stream_params, unsigned int latency,
|
||||
cubeb_data_callback data_callback, cubeb_state_callback state_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
cubeb_stream * stm;
|
||||
|
||||
@ -482,8 +482,8 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
|
||||
format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
|
||||
format.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
|
||||
format.channelMask = stream_params.channels == 1 ?
|
||||
SL_SPEAKER_FRONT_CENTER :
|
||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
|
||||
SL_SPEAKER_FRONT_CENTER :
|
||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
|
||||
|
||||
switch (stream_params.format) {
|
||||
case CUBEB_SAMPLE_S16LE:
|
||||
@ -588,9 +588,9 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
|
||||
if (stream_type != 0xFFFFFFFF) {
|
||||
SLAndroidConfigurationItf playerConfig;
|
||||
res = (*stm->playerObj)->GetInterface(stm->playerObj,
|
||||
ctx->SL_IID_ANDROIDCONFIGURATION, &playerConfig);
|
||||
ctx->SL_IID_ANDROIDCONFIGURATION, &playerConfig);
|
||||
res = (*playerConfig)->SetConfiguration(playerConfig,
|
||||
SL_ANDROID_KEY_STREAM_TYPE, &stream_type, sizeof(SLint32));
|
||||
SL_ANDROID_KEY_STREAM_TYPE, &stream_type, sizeof(SLint32));
|
||||
if (res != SL_RESULT_SUCCESS) {
|
||||
opensl_stream_destroy(stm);
|
||||
return CUBEB_ERROR;
|
||||
@ -611,7 +611,7 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name
|
||||
}
|
||||
|
||||
res = (*stm->playerObj)->GetInterface(stm->playerObj, ctx->SL_IID_BUFFERQUEUE,
|
||||
&stm->bufq);
|
||||
&stm->bufq);
|
||||
if (res != SL_RESULT_SUCCESS) {
|
||||
opensl_stream_destroy(stm);
|
||||
return CUBEB_ERROR;
|
||||
@ -667,7 +667,7 @@ static int
|
||||
opensl_stream_start(cubeb_stream * stm)
|
||||
{
|
||||
/* To refill the queues before starting playback in order to avoid racing
|
||||
* with refills started by SetPlayState on OpenSLES ndk threads. */
|
||||
* with refills started by SetPlayState on OpenSLES ndk threads. */
|
||||
bufferqueue_callback(NULL, stm);
|
||||
SLresult res = (*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PLAYING);
|
||||
if (res != SL_RESULT_SUCCESS)
|
||||
@ -692,7 +692,7 @@ opensl_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
SLmillisecond msec;
|
||||
uint64_t samplerate;
|
||||
SLresult res;
|
||||
int rv;
|
||||
int r;
|
||||
uint32_t mixer_latency;
|
||||
|
||||
res = (*stm->play)->GetPosition(stm->play, &msec);
|
||||
@ -701,8 +701,8 @@ opensl_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
|
||||
samplerate = stm->inputrate;
|
||||
|
||||
rv = stm->context->get_output_latency(&mixer_latency, stm->stream_type);
|
||||
if (rv) {
|
||||
r = stm->context->get_output_latency(&mixer_latency, stm->stream_type);
|
||||
if (r) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
@ -714,7 +714,7 @@ opensl_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
if (msec > mixer_latency) {
|
||||
int64_t unadjusted_position = samplerate * (msec - mixer_latency) / 1000;
|
||||
*position = unadjusted_position < maximum_position ?
|
||||
unadjusted_position : maximum_position;
|
||||
unadjusted_position : maximum_position;
|
||||
} else {
|
||||
*position = 0;
|
||||
}
|
||||
@ -724,17 +724,17 @@ opensl_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
int
|
||||
opensl_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
|
||||
{
|
||||
int rv;
|
||||
int r;
|
||||
uint32_t mixer_latency; // The latency returned by AudioFlinger is in ms.
|
||||
|
||||
/* audio_stream_type_t is an int, so this is okay. */
|
||||
rv = stm->context->get_output_latency(&mixer_latency, stm->stream_type);
|
||||
if (rv) {
|
||||
r = stm->context->get_output_latency(&mixer_latency, stm->stream_type);
|
||||
if (r) {
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
*latency = stm->latency * stm->inputrate / 1000 + // OpenSL latency
|
||||
mixer_latency * stm->inputrate / 1000; // AudioFlinger latency
|
||||
mixer_latency * stm->inputrate / 1000; // AudioFlinger latency
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
@ -770,14 +770,6 @@ opensl_stream_set_volume(cubeb_stream * stm, float volume)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
opensl_stream_set_panning(cubeb_stream * stream, float panning)
|
||||
{
|
||||
assert(0 && "not implemented.");
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const opensl_ops = {
|
||||
.init = opensl_init,
|
||||
.get_backend_id = opensl_get_backend_id,
|
||||
@ -792,7 +784,7 @@ static struct cubeb_ops const opensl_ops = {
|
||||
.stream_get_position = opensl_stream_get_position,
|
||||
.stream_get_latency = opensl_stream_get_latency,
|
||||
.stream_set_volume = opensl_stream_set_volume,
|
||||
.stream_set_panning = opensl_stream_set_panning,
|
||||
.stream_set_panning = NULL,
|
||||
.stream_get_current_device = NULL,
|
||||
.stream_device_destroy = NULL,
|
||||
.stream_register_device_changed_callback = NULL
|
||||
|
@ -18,55 +18,58 @@
|
||||
#define WRAP(x) x
|
||||
#else
|
||||
#define WRAP(x) cubeb_##x
|
||||
#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x
|
||||
MAKE_TYPEDEF(pa_channel_map_can_balance);
|
||||
MAKE_TYPEDEF(pa_channel_map_init_auto);
|
||||
MAKE_TYPEDEF(pa_context_connect);
|
||||
MAKE_TYPEDEF(pa_context_disconnect);
|
||||
MAKE_TYPEDEF(pa_context_drain);
|
||||
MAKE_TYPEDEF(pa_context_get_server_info);
|
||||
MAKE_TYPEDEF(pa_context_get_sink_info_by_name);
|
||||
MAKE_TYPEDEF(pa_context_get_state);
|
||||
MAKE_TYPEDEF(pa_context_new);
|
||||
MAKE_TYPEDEF(pa_context_rttime_new);
|
||||
MAKE_TYPEDEF(pa_context_set_sink_input_volume);
|
||||
MAKE_TYPEDEF(pa_context_set_state_callback);
|
||||
MAKE_TYPEDEF(pa_context_unref);
|
||||
MAKE_TYPEDEF(pa_cvolume_set);
|
||||
MAKE_TYPEDEF(pa_cvolume_set_balance);
|
||||
MAKE_TYPEDEF(pa_frame_size);
|
||||
MAKE_TYPEDEF(pa_operation_get_state);
|
||||
MAKE_TYPEDEF(pa_operation_unref);
|
||||
MAKE_TYPEDEF(pa_rtclock_now);
|
||||
MAKE_TYPEDEF(pa_stream_begin_write);
|
||||
MAKE_TYPEDEF(pa_stream_cancel_write);
|
||||
MAKE_TYPEDEF(pa_stream_connect_playback);
|
||||
MAKE_TYPEDEF(pa_stream_cork);
|
||||
MAKE_TYPEDEF(pa_stream_disconnect);
|
||||
MAKE_TYPEDEF(pa_stream_get_channel_map);
|
||||
MAKE_TYPEDEF(pa_stream_get_index);
|
||||
MAKE_TYPEDEF(pa_stream_get_latency);
|
||||
MAKE_TYPEDEF(pa_stream_get_sample_spec);
|
||||
MAKE_TYPEDEF(pa_stream_get_state);
|
||||
MAKE_TYPEDEF(pa_stream_get_time);
|
||||
MAKE_TYPEDEF(pa_stream_new);
|
||||
MAKE_TYPEDEF(pa_stream_set_state_callback);
|
||||
MAKE_TYPEDEF(pa_stream_set_write_callback);
|
||||
MAKE_TYPEDEF(pa_stream_unref);
|
||||
MAKE_TYPEDEF(pa_stream_update_timing_info);
|
||||
MAKE_TYPEDEF(pa_stream_write);
|
||||
MAKE_TYPEDEF(pa_sw_volume_from_linear);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_free);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_get_api);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_in_thread);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_lock);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_new);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_signal);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_start);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_stop);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_unlock);
|
||||
MAKE_TYPEDEF(pa_threaded_mainloop_wait);
|
||||
MAKE_TYPEDEF(pa_usec_to_bytes);
|
||||
#define LIBPULSE_API_VISIT(X) \
|
||||
X(pa_channel_map_can_balance) \
|
||||
X(pa_channel_map_init_auto) \
|
||||
X(pa_context_connect) \
|
||||
X(pa_context_disconnect) \
|
||||
X(pa_context_drain) \
|
||||
X(pa_context_get_server_info) \
|
||||
X(pa_context_get_sink_info_by_name) \
|
||||
X(pa_context_get_state) \
|
||||
X(pa_context_new) \
|
||||
X(pa_context_rttime_new) \
|
||||
X(pa_context_set_sink_input_volume) \
|
||||
X(pa_context_set_state_callback) \
|
||||
X(pa_context_unref) \
|
||||
X(pa_cvolume_set) \
|
||||
X(pa_cvolume_set_balance) \
|
||||
X(pa_frame_size) \
|
||||
X(pa_operation_get_state) \
|
||||
X(pa_operation_unref) \
|
||||
X(pa_rtclock_now) \
|
||||
X(pa_stream_begin_write) \
|
||||
X(pa_stream_cancel_write) \
|
||||
X(pa_stream_connect_playback) \
|
||||
X(pa_stream_cork) \
|
||||
X(pa_stream_disconnect) \
|
||||
X(pa_stream_get_channel_map) \
|
||||
X(pa_stream_get_index) \
|
||||
X(pa_stream_get_latency) \
|
||||
X(pa_stream_get_sample_spec) \
|
||||
X(pa_stream_get_state) \
|
||||
X(pa_stream_get_time) \
|
||||
X(pa_stream_new) \
|
||||
X(pa_stream_set_state_callback) \
|
||||
X(pa_stream_set_write_callback) \
|
||||
X(pa_stream_unref) \
|
||||
X(pa_stream_update_timing_info) \
|
||||
X(pa_stream_write) \
|
||||
X(pa_sw_volume_from_linear) \
|
||||
X(pa_threaded_mainloop_free) \
|
||||
X(pa_threaded_mainloop_get_api) \
|
||||
X(pa_threaded_mainloop_in_thread) \
|
||||
X(pa_threaded_mainloop_lock) \
|
||||
X(pa_threaded_mainloop_new) \
|
||||
X(pa_threaded_mainloop_signal) \
|
||||
X(pa_threaded_mainloop_start) \
|
||||
X(pa_threaded_mainloop_stop) \
|
||||
X(pa_threaded_mainloop_unlock) \
|
||||
X(pa_threaded_mainloop_wait) \
|
||||
X(pa_usec_to_bytes) \
|
||||
|
||||
#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
|
||||
LIBPULSE_API_VISIT(MAKE_TYPEDEF);
|
||||
#undef MAKE_TYPEDEF
|
||||
#endif
|
||||
|
||||
@ -314,7 +317,7 @@ pulse_context_init(cubeb * ctx)
|
||||
}
|
||||
|
||||
ctx->context = WRAP(pa_context_new)(WRAP(pa_threaded_mainloop_get_api)(ctx->mainloop),
|
||||
ctx->context_name);
|
||||
ctx->context_name);
|
||||
WRAP(pa_context_set_state_callback)(ctx->context, context_state_callback, ctx);
|
||||
|
||||
WRAP(pa_threaded_mainloop_lock)(ctx->mainloop);
|
||||
@ -348,61 +351,15 @@ pulse_init(cubeb ** context, char const * context_name)
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
#define LOAD(x) do { \
|
||||
cubeb_##x = dlsym(libpulse, #x); \
|
||||
if (!cubeb_##x) { \
|
||||
dlclose(libpulse); \
|
||||
return CUBEB_ERROR; \
|
||||
} \
|
||||
} while(0)
|
||||
LOAD(pa_channel_map_can_balance);
|
||||
LOAD(pa_channel_map_init_auto);
|
||||
LOAD(pa_context_connect);
|
||||
LOAD(pa_context_disconnect);
|
||||
LOAD(pa_context_drain);
|
||||
LOAD(pa_context_get_server_info);
|
||||
LOAD(pa_context_get_sink_info_by_name);
|
||||
LOAD(pa_context_get_state);
|
||||
LOAD(pa_context_new);
|
||||
LOAD(pa_context_rttime_new);
|
||||
LOAD(pa_context_set_sink_input_volume);
|
||||
LOAD(pa_context_set_state_callback);
|
||||
LOAD(pa_context_unref);
|
||||
LOAD(pa_cvolume_set);
|
||||
LOAD(pa_cvolume_set_balance);
|
||||
LOAD(pa_frame_size);
|
||||
LOAD(pa_operation_get_state);
|
||||
LOAD(pa_operation_unref);
|
||||
LOAD(pa_rtclock_now);
|
||||
LOAD(pa_stream_begin_write);
|
||||
LOAD(pa_stream_cancel_write);
|
||||
LOAD(pa_stream_connect_playback);
|
||||
LOAD(pa_stream_cork);
|
||||
LOAD(pa_stream_disconnect);
|
||||
LOAD(pa_stream_get_channel_map);
|
||||
LOAD(pa_stream_get_index);
|
||||
LOAD(pa_stream_get_latency);
|
||||
LOAD(pa_stream_get_sample_spec);
|
||||
LOAD(pa_stream_get_state);
|
||||
LOAD(pa_stream_get_time);
|
||||
LOAD(pa_stream_new);
|
||||
LOAD(pa_stream_set_state_callback);
|
||||
LOAD(pa_stream_set_write_callback);
|
||||
LOAD(pa_stream_unref);
|
||||
LOAD(pa_stream_update_timing_info);
|
||||
LOAD(pa_stream_write);
|
||||
LOAD(pa_sw_volume_from_linear);
|
||||
LOAD(pa_threaded_mainloop_free);
|
||||
LOAD(pa_threaded_mainloop_get_api);
|
||||
LOAD(pa_threaded_mainloop_in_thread);
|
||||
LOAD(pa_threaded_mainloop_lock);
|
||||
LOAD(pa_threaded_mainloop_new);
|
||||
LOAD(pa_threaded_mainloop_signal);
|
||||
LOAD(pa_threaded_mainloop_start);
|
||||
LOAD(pa_threaded_mainloop_stop);
|
||||
LOAD(pa_threaded_mainloop_unlock);
|
||||
LOAD(pa_threaded_mainloop_wait);
|
||||
LOAD(pa_usec_to_bytes);
|
||||
#define LOAD(x) { \
|
||||
cubeb_##x = dlsym(libpulse, #x); \
|
||||
if (!cubeb_##x) { \
|
||||
dlclose(libpulse); \
|
||||
return CUBEB_ERROR; \
|
||||
} \
|
||||
}
|
||||
|
||||
LIBPULSE_API_VISIT(LOAD);
|
||||
#undef LOAD
|
||||
#endif
|
||||
|
||||
@ -590,9 +547,9 @@ pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
|
||||
WRAP(pa_stream_set_state_callback)(stm->stream, stream_state_callback, stm);
|
||||
WRAP(pa_stream_set_write_callback)(stm->stream, stream_request_callback, stm);
|
||||
WRAP(pa_stream_connect_playback)(stm->stream, NULL, &battr,
|
||||
PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING |
|
||||
PA_STREAM_START_CORKED,
|
||||
NULL, NULL);
|
||||
PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING |
|
||||
PA_STREAM_START_CORKED,
|
||||
NULL, NULL);
|
||||
|
||||
r = wait_until_stream_ready(stm);
|
||||
if (r == 0) {
|
||||
|
@ -342,13 +342,6 @@ sndio_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
sndio_stream_set_panning(cubeb_stream * stm, float panning)
|
||||
{
|
||||
assert(false && "not implemented");
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const sndio_ops = {
|
||||
.init = sndio_init,
|
||||
.get_backend_id = sndio_get_backend_id,
|
||||
@ -363,7 +356,7 @@ static struct cubeb_ops const sndio_ops = {
|
||||
.stream_get_position = sndio_stream_get_position,
|
||||
.stream_get_latency = sndio_stream_get_latency,
|
||||
.stream_set_volume = sndio_stream_set_volume,
|
||||
.stream_set_panning = sndio_stream_set_panning,
|
||||
.stream_set_panning = NULL,
|
||||
.stream_get_current_device = NULL,
|
||||
.stream_device_destroy = NULL,
|
||||
.stream_register_device_changed_callback = NULL
|
||||
|
@ -946,12 +946,6 @@ int wasapi_stream_set_volume(cubeb_stream * stm, float volume)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int wasapi_stream_set_panning(cubeb_stream * stream, float panning)
|
||||
{
|
||||
assert(false && "not implemented");
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
cubeb_ops const wasapi_ops = {
|
||||
/*.init =*/ wasapi_init,
|
||||
/*.get_backend_id =*/ wasapi_get_backend_id,
|
||||
@ -966,7 +960,7 @@ cubeb_ops const wasapi_ops = {
|
||||
/*.stream_get_position =*/ wasapi_stream_get_position,
|
||||
/*.stream_get_latency =*/ wasapi_stream_get_latency,
|
||||
/*.stream_set_volume =*/ wasapi_stream_set_volume,
|
||||
/*.stream_set_panning =*/ wasapi_stream_set_panning,
|
||||
/*.stream_set_panning =*/ NULL,
|
||||
/*.stream_get_current_device =*/ NULL,
|
||||
/*.stream_device_destroy =*/ NULL,
|
||||
/*.stream_register_device_changed_callback =*/ NULL
|
||||
|
@ -200,11 +200,11 @@ winmm_buffer_thread(void * user_ptr)
|
||||
assert(ctx);
|
||||
|
||||
for (;;) {
|
||||
DWORD rv;
|
||||
DWORD r;
|
||||
PSLIST_ENTRY item;
|
||||
|
||||
rv = WaitForSingleObject(ctx->event, INFINITE);
|
||||
assert(rv == WAIT_OBJECT_0);
|
||||
r = WaitForSingleObject(ctx->event, INFINITE);
|
||||
assert(r == WAIT_OBJECT_0);
|
||||
|
||||
/* Process work items in batches so that a single stream can't
|
||||
starve the others by continuously adding new work to the top of
|
||||
@ -323,7 +323,7 @@ winmm_get_backend_id(cubeb * ctx)
|
||||
static void
|
||||
winmm_destroy(cubeb * ctx)
|
||||
{
|
||||
DWORD rv;
|
||||
DWORD r;
|
||||
|
||||
assert(ctx->active_streams == 0);
|
||||
assert(!InterlockedPopEntrySList(ctx->work));
|
||||
@ -333,8 +333,8 @@ winmm_destroy(cubeb * ctx)
|
||||
if (ctx->thread) {
|
||||
ctx->shutdown = 1;
|
||||
SetEvent(ctx->event);
|
||||
rv = WaitForSingleObject(ctx->thread, INFINITE);
|
||||
assert(rv == WAIT_OBJECT_0);
|
||||
r = WaitForSingleObject(ctx->thread, INFINITE);
|
||||
assert(r == WAIT_OBJECT_0);
|
||||
CloseHandle(ctx->thread);
|
||||
}
|
||||
|
||||
@ -488,7 +488,7 @@ winmm_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n
|
||||
static void
|
||||
winmm_stream_destroy(cubeb_stream * stm)
|
||||
{
|
||||
DWORD rv;
|
||||
DWORD r;
|
||||
int i;
|
||||
int enqueued;
|
||||
|
||||
@ -503,8 +503,8 @@ winmm_stream_destroy(cubeb_stream * stm)
|
||||
|
||||
/* Wait for all blocks to complete. */
|
||||
while (enqueued > 0) {
|
||||
rv = WaitForSingleObject(stm->event, INFINITE);
|
||||
assert(rv == WAIT_OBJECT_0);
|
||||
r = WaitForSingleObject(stm->event, INFINITE);
|
||||
assert(r == WAIT_OBJECT_0);
|
||||
|
||||
EnterCriticalSection(&stm->lock);
|
||||
enqueued = NBUFS - stm->free_buffers;
|
||||
@ -668,13 +668,6 @@ winmm_stream_set_volume(cubeb_stream * stm, float volume)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
winmm_stream_set_panning(cubeb_stream * stream, float panning)
|
||||
{
|
||||
assert(0 && "not implemented");
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static struct cubeb_ops const winmm_ops = {
|
||||
/*.init =*/ winmm_init,
|
||||
/*.get_backend_id =*/ winmm_get_backend_id,
|
||||
@ -689,7 +682,7 @@ static struct cubeb_ops const winmm_ops = {
|
||||
/*.stream_get_position =*/ winmm_stream_get_position,
|
||||
/*.stream_get_latency = */ winmm_stream_get_latency,
|
||||
/*.stream_set_volume =*/ winmm_stream_set_volume,
|
||||
/*.stream_set_panning =*/ winmm_stream_set_panning,
|
||||
/*.stream_set_panning =*/ NULL,
|
||||
/*.stream_get_current_device =*/ NULL,
|
||||
/*.stream_device_destroy =*/ NULL,
|
||||
/*.stream_register_device_changed_callback=*/ NULL
|
||||
|
@ -114,15 +114,15 @@ int supports_channel_count(const char* backend_id, int nchannels)
|
||||
|
||||
int run_test(int num_channels, int sampling_rate, int is_float)
|
||||
{
|
||||
int ret = CUBEB_OK;
|
||||
int r = CUBEB_OK;
|
||||
|
||||
cubeb *ctx = NULL;
|
||||
synth_state* synth = NULL;
|
||||
cubeb_stream *stream = NULL;
|
||||
const char * backend_id = NULL;
|
||||
|
||||
ret = cubeb_init(&ctx, "Cubeb audio test");
|
||||
if (ret != CUBEB_OK) {
|
||||
r = cubeb_init(&ctx, "Cubeb audio test: channels");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
goto cleanup;
|
||||
}
|
||||
@ -148,10 +148,10 @@ int run_test(int num_channels, int sampling_rate, int is_float)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = cubeb_stream_init(ctx, &stream, "test tone", params,
|
||||
100, is_float ? data_cb_float : data_cb_short, state_cb, synth);
|
||||
if (ret != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream: %d\n", ret);
|
||||
r = cubeb_stream_init(ctx, &stream, "test tone", params,
|
||||
100, is_float ? data_cb_float : data_cb_short, state_cb, synth);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream: %d\n", r);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -164,10 +164,74 @@ cleanup:
|
||||
cubeb_destroy(ctx);
|
||||
synth_destroy(synth);
|
||||
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int run_panning_volume_test()
|
||||
{
|
||||
int r = CUBEB_OK;
|
||||
|
||||
cubeb *ctx = NULL;
|
||||
synth_state* synth = NULL;
|
||||
cubeb_stream *stream = NULL;
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cubeb_stream_params params;
|
||||
params.format = CUBEB_SAMPLE_S16NE;
|
||||
params.rate = 44100;
|
||||
params.channels = 2;
|
||||
|
||||
synth = synth_create(params.channels, params.rate);
|
||||
if (synth == NULL) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "test tone", params,
|
||||
100, data_cb_short, state_cb, synth);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream: %d\n", r);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Testing: volume\n");
|
||||
for(int i=0;i <= 4; ++i)
|
||||
{
|
||||
fprintf(stderr, "Volume: %d%%\n", i*25);
|
||||
|
||||
cubeb_stream_set_volume(stream, i/4.0f);
|
||||
cubeb_stream_start(stream);
|
||||
delay(400);
|
||||
cubeb_stream_stop(stream);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Testing: panning\n");
|
||||
for(int i=-4;i <= 4; ++i)
|
||||
{
|
||||
fprintf(stderr, "Panning: %.2f%%\n", i/4.0f);
|
||||
|
||||
cubeb_stream_set_panning(stream, i/4.0f);
|
||||
cubeb_stream_start(stream);
|
||||
delay(400);
|
||||
cubeb_stream_stop(stream);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
cubeb_stream_destroy(stream);
|
||||
cubeb_destroy(ctx);
|
||||
synth_destroy(synth);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void run_channel_rate_test()
|
||||
{
|
||||
int channel_values[] = {
|
||||
1,
|
||||
@ -192,8 +256,13 @@ int main(int argc, char *argv[])
|
||||
assert(run_test(channel_values[j], freq_values[i], 1) == CUBEB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
assert(run_panning_volume_test() == CUBEB_OK);
|
||||
run_channel_rate_test();
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
@ -11,35 +11,41 @@
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
cubeb * ctx = NULL;
|
||||
int rv;
|
||||
int r;
|
||||
uint32_t max_channels;
|
||||
uint32_t preferred_rate;
|
||||
uint32_t latency_ms;
|
||||
|
||||
LOG("latency_test start");
|
||||
rv = cubeb_init(&ctx, "Cubeb audio test");
|
||||
assert(rv == CUBEB_OK && "Cubeb init failed.");
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
assert(r == CUBEB_OK && "Cubeb init failed.");
|
||||
LOG("cubeb_init ok");
|
||||
|
||||
rv = cubeb_get_max_channel_count(ctx, &max_channels);
|
||||
assert(rv == CUBEB_OK && "Could not query the max channe count.");
|
||||
assert(max_channels > 0 && "Invalid max channel count.");
|
||||
LOG("cubeb_get_max_channel_count ok");
|
||||
r = cubeb_get_max_channel_count(ctx, &max_channels);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(max_channels > 0 && "Invalid max channel count.");
|
||||
LOG("cubeb_get_max_channel_count ok");
|
||||
}
|
||||
|
||||
rv = cubeb_get_preferred_sample_rate(ctx, &preferred_rate);
|
||||
assert(rv == CUBEB_OK && "Could not query the preferred sample rate.");
|
||||
assert(preferred_rate && "Invalid preferred sample rate.");
|
||||
LOG("cubeb_get_preferred_sample_rate ok");
|
||||
r = cubeb_get_preferred_sample_rate(ctx, &preferred_rate);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(preferred_rate > 0 && "Invalid preferred sample rate.");
|
||||
LOG("cubeb_get_preferred_sample_rate ok");
|
||||
}
|
||||
|
||||
cubeb_stream_params params = {
|
||||
CUBEB_SAMPLE_FLOAT32NE,
|
||||
preferred_rate,
|
||||
max_channels
|
||||
};
|
||||
rv = cubeb_get_min_latency(ctx, params, &latency_ms);
|
||||
assert(rv == CUBEB_OK && "Could not query the minimal latency.");
|
||||
assert(latency_ms && "Invalid minimal latency.");
|
||||
LOG("cubeb_get_min_latency ok");
|
||||
r = cubeb_get_min_latency(ctx, params, &latency_ms);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(latency_ms > 0 && "Invalid minimal latency.");
|
||||
LOG("cubeb_get_min_latency ok");
|
||||
}
|
||||
|
||||
cubeb_destroy(ctx);
|
||||
LOG("cubeb_destroy ok");
|
||||
|
@ -54,16 +54,23 @@ test_init_destroy_context(void)
|
||||
{
|
||||
int r;
|
||||
cubeb * ctx;
|
||||
char const* backend_id;
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
|
||||
backend_id = cubeb_get_backend_id(ctx);
|
||||
assert(backend_id);
|
||||
|
||||
fprintf(stderr, "Backend: %s\n", backend_id);
|
||||
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_init_destroy_multiple_contexts(void)
|
||||
@ -76,10 +83,10 @@ test_init_destroy_multiple_contexts(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(ctx); ++i) {
|
||||
r = cubeb_init(&ctx[i], NULL);
|
||||
assert(r == 0 && ctx[i]);
|
||||
}
|
||||
for (i = 0; i < ARRAY_LENGTH(ctx); ++i) {
|
||||
r = cubeb_init(&ctx[i], NULL);
|
||||
assert(r == 0 && ctx[i]);
|
||||
}
|
||||
|
||||
/* destroy in a different order */
|
||||
for (i = 0; i < ARRAY_LENGTH(ctx); ++i) {
|
||||
@ -87,7 +94,40 @@ test_init_destroy_multiple_contexts(void)
|
||||
}
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_context_variables(void)
|
||||
{
|
||||
int r;
|
||||
cubeb * ctx;
|
||||
uint32_t value;
|
||||
cubeb_stream_params params;
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_context_variables");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
params.channels = 2;
|
||||
params.format = CUBEB_SAMPLE_S16LE;
|
||||
params.rate = 44100;
|
||||
r = cubeb_get_min_latency(ctx, params, &value);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(value > 0);
|
||||
}
|
||||
|
||||
r = cubeb_get_preferred_sample_rate(ctx, &value);
|
||||
assert(r == CUBEB_OK || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
if (r == CUBEB_OK) {
|
||||
assert(value > 0);
|
||||
}
|
||||
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
|
||||
static void
|
||||
test_init_destroy_stream(void)
|
||||
@ -99,7 +139,7 @@ test_init_destroy_stream(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
@ -114,7 +154,7 @@ test_init_destroy_stream(void)
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_init_destroy_multiple_streams(void)
|
||||
@ -127,7 +167,7 @@ test_init_destroy_multiple_streams(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
@ -148,7 +188,39 @@ test_init_destroy_multiple_streams(void)
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_configure_stream(void)
|
||||
{
|
||||
int r;
|
||||
cubeb * ctx;
|
||||
cubeb_stream * stream;
|
||||
cubeb_stream_params params;
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = 2; // panning
|
||||
|
||||
r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY,
|
||||
test_data_callback, test_state_callback, &dummy);
|
||||
assert(r == 0 && stream);
|
||||
|
||||
r = cubeb_stream_set_volume(stream, 1.0f);
|
||||
assert(r == 0 || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
|
||||
r = cubeb_stream_set_panning(stream, 0.0f);
|
||||
assert(r == 0 || r == CUBEB_ERROR_NOT_SUPPORTED);
|
||||
|
||||
cubeb_stream_destroy(stream);
|
||||
cubeb_destroy(ctx);
|
||||
END_TEST
|
||||
}
|
||||
|
||||
static void
|
||||
test_init_start_stop_destroy_multiple_streams(int early, int delay_ms)
|
||||
@ -161,7 +233,7 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
@ -209,7 +281,7 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms)
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_init_destroy_multiple_contexts_and_streams(void)
|
||||
@ -224,7 +296,7 @@ test_init_destroy_multiple_contexts_and_streams(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
params.format = STREAM_FORMAT;
|
||||
params.rate = STREAM_RATE;
|
||||
params.channels = STREAM_CHANNELS;
|
||||
|
||||
@ -248,7 +320,7 @@ test_init_destroy_multiple_contexts_and_streams(void)
|
||||
}
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_basic_stream_operations(void)
|
||||
@ -261,7 +333,7 @@ test_basic_stream_operations(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
|
||||
params.format = STREAM_FORMAT;
|
||||
@ -294,7 +366,7 @@ test_basic_stream_operations(void)
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_stream_position(void)
|
||||
@ -308,7 +380,7 @@ test_stream_position(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
total_frames_written = 0;
|
||||
total_frames_written = 0;
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
@ -384,7 +456,7 @@ test_stream_position(void)
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
static int do_drain;
|
||||
static int got_drain;
|
||||
@ -424,7 +496,7 @@ test_drain(void)
|
||||
|
||||
BEGIN_TEST
|
||||
|
||||
total_frames_written = 0;
|
||||
total_frames_written = 0;
|
||||
|
||||
r = cubeb_init(&ctx, "test_sanity");
|
||||
assert(r == 0 && ctx);
|
||||
@ -467,30 +539,30 @@ test_drain(void)
|
||||
cubeb_destroy(ctx);
|
||||
|
||||
END_TEST
|
||||
}
|
||||
}
|
||||
|
||||
int is_windows_7()
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
printf("Warning: this test was built with MinGW.\n"
|
||||
"MinGW does not contain necessary version checking infrastructure. Claiming to be Windows 7, even if we're not.\n");
|
||||
return 1;
|
||||
printf("Warning: this test was built with MinGW.\n"
|
||||
"MinGW does not contain necessary version checking infrastructure. Claiming to be Windows 7, even if we're not.\n");
|
||||
return 1;
|
||||
#endif
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && ( !defined(__MINGW32__))
|
||||
OSVERSIONINFOEX osvi;
|
||||
DWORDLONG condition_mask = 0;
|
||||
OSVERSIONINFOEX osvi;
|
||||
DWORDLONG condition_mask = 0;
|
||||
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
|
||||
// NT 6.1 is Windows 7
|
||||
osvi.dwMajorVersion = 6;
|
||||
osvi.dwMinorVersion = 1;
|
||||
// NT 6.1 is Windows 7
|
||||
osvi.dwMajorVersion = 6;
|
||||
osvi.dwMinorVersion = 1;
|
||||
|
||||
VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, VER_EQUAL);
|
||||
VER_SET_CONDITION(condition_mask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, VER_EQUAL);
|
||||
VER_SET_CONDITION(condition_mask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
|
||||
return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, condition_mask);
|
||||
return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, condition_mask);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@ -501,8 +573,10 @@ main(int argc, char * argv[])
|
||||
{
|
||||
test_init_destroy_context();
|
||||
test_init_destroy_multiple_contexts();
|
||||
test_context_variables();
|
||||
test_init_destroy_stream();
|
||||
test_init_destroy_multiple_streams();
|
||||
test_configure_stream();
|
||||
test_basic_stream_operations();
|
||||
test_stream_position();
|
||||
|
||||
|
@ -57,14 +57,14 @@ void state_cb(cubeb_stream *stream, void *user, cubeb_state state)
|
||||
return;
|
||||
|
||||
switch (state) {
|
||||
case CUBEB_STATE_STARTED:
|
||||
printf("stream started\n"); break;
|
||||
case CUBEB_STATE_STOPPED:
|
||||
printf("stream stopped\n"); break;
|
||||
case CUBEB_STATE_DRAINED:
|
||||
printf("stream drained\n"); break;
|
||||
default:
|
||||
printf("unknown stream state %d\n", state);
|
||||
case CUBEB_STATE_STARTED:
|
||||
printf("stream started\n"); break;
|
||||
case CUBEB_STATE_STOPPED:
|
||||
printf("stream stopped\n"); break;
|
||||
case CUBEB_STATE_DRAINED:
|
||||
printf("stream drained\n"); break;
|
||||
default:
|
||||
printf("unknown stream state %d\n", state);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -76,12 +76,12 @@ int main(int argc, char *argv[])
|
||||
cubeb_stream *stream;
|
||||
cubeb_stream_params params;
|
||||
struct cb_user_data *user_data;
|
||||
int ret;
|
||||
int r;
|
||||
|
||||
ret = cubeb_init(&ctx, "Cubeb tone example");
|
||||
if (ret != CUBEB_OK) {
|
||||
r = cubeb_init(&ctx, "Cubeb tone example");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
params.format = CUBEB_SAMPLE_S16NE;
|
||||
@ -95,11 +95,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
user_data->position = 0;
|
||||
|
||||
ret = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params,
|
||||
250, data_cb, state_cb, user_data);
|
||||
if (ret != CUBEB_OK) {
|
||||
r = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params,
|
||||
250, data_cb, state_cb, user_data);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb stream\n");
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
cubeb_stream_start(stream);
|
||||
|
Loading…
Reference in New Issue
Block a user