summaryrefslogtreecommitdiff
path: root/media/libcubeb/src/cubeb.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libcubeb/src/cubeb.c')
-rw-r--r--media/libcubeb/src/cubeb.c477
1 files changed, 165 insertions, 312 deletions
diff --git a/media/libcubeb/src/cubeb.c b/media/libcubeb/src/cubeb.c
index b3d32eea3d..a239319a46 100644
--- a/media/libcubeb/src/cubeb.c
+++ b/media/libcubeb/src/cubeb.c
@@ -5,121 +5,88 @@
* accompanying file LICENSE for details.
*/
#undef NDEBUG
-#include "cubeb/cubeb.h"
-#include "cubeb-internal.h"
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
-#include <string.h>
+#include "cubeb/cubeb.h"
+#include "cubeb-internal.h"
-#define NELEMS(x) ((int)(sizeof(x) / sizeof(x[0])))
+#define NELEMS(x) ((int) (sizeof(x) / sizeof(x[0])))
+
+cubeb_log_level g_log_level;
+cubeb_log_callback g_log_callback;
struct cubeb {
struct cubeb_ops * ops;
};
struct cubeb_stream {
- /*
- * Note: All implementations of cubeb_stream must keep the following
- * layout.
- */
struct cubeb * context;
- void * user_ptr;
};
#if defined(USE_PULSE)
-int
-pulse_init(cubeb ** context, char const * context_name);
-#endif
-#if defined(USE_PULSE_RUST)
-int
-pulse_rust_init(cubeb ** contet, char const * context_name);
+int pulse_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_JACK)
-int
-jack_init(cubeb ** context, char const * context_name);
+int jack_init (cubeb ** context, char const * context_name);
#endif
#if defined(USE_ALSA)
-int
-alsa_init(cubeb ** context, char const * context_name);
+int alsa_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_AUDIOUNIT)
-int
-audiounit_init(cubeb ** context, char const * context_name);
-#endif
-#if defined(USE_AUDIOUNIT_RUST)
-int
-audiounit_rust_init(cubeb ** contet, char const * context_name);
+int audiounit_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_WINMM)
-int
-winmm_init(cubeb ** context, char const * context_name);
+int winmm_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_WASAPI)
-int
-wasapi_init(cubeb ** context, char const * context_name);
+int wasapi_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_SNDIO)
-int
-sndio_init(cubeb ** context, char const * context_name);
-#endif
-#if defined(USE_SUN)
-int
-sun_init(cubeb ** context, char const * context_name);
+int sndio_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_OPENSL)
-int
-opensl_init(cubeb ** context, char const * context_name);
-#endif
-#if defined(USE_OSS)
-int
-oss_init(cubeb ** context, char const * context_name);
-#endif
-#if defined(USE_AAUDIO)
-int
-aaudio_init(cubeb ** context, char const * context_name);
+int opensl_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_AUDIOTRACK)
-int
-audiotrack_init(cubeb ** context, char const * context_name);
+int audiotrack_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_KAI)
-int
-kai_init(cubeb ** context, char const * context_name);
+int kai_init(cubeb ** context, char const * context_name);
+#endif
+#if defined(USE_SUN)
+int sunaudio_init(cubeb ** context, char const * context_name);
#endif
+
static int
validate_stream_params(cubeb_stream_params * input_stream_params,
cubeb_stream_params * output_stream_params)
{
XASSERT(input_stream_params || output_stream_params);
if (output_stream_params) {
- if (output_stream_params->rate < 1000 ||
- output_stream_params->rate > 192000 ||
- output_stream_params->channels < 1 ||
- output_stream_params->channels > UINT8_MAX) {
+ if (output_stream_params->rate < 1000 || output_stream_params->rate > 192000 ||
+ output_stream_params->channels < 1 || output_stream_params->channels > 8) {
return CUBEB_ERROR_INVALID_FORMAT;
}
}
if (input_stream_params) {
- if (input_stream_params->rate < 1000 ||
- input_stream_params->rate > 192000 ||
- input_stream_params->channels < 1 ||
- input_stream_params->channels > UINT8_MAX) {
+ if (input_stream_params->rate < 1000 || input_stream_params->rate > 192000 ||
+ input_stream_params->channels < 1 || input_stream_params->channels > 8) {
return CUBEB_ERROR_INVALID_FORMAT;
}
}
// Rate and sample format must be the same for input and output, if using a
// duplex stream
if (input_stream_params && output_stream_params) {
- if (input_stream_params->rate != output_stream_params->rate ||
+ if (input_stream_params->rate != output_stream_params->rate ||
input_stream_params->format != output_stream_params->format) {
return CUBEB_ERROR_INVALID_FORMAT;
}
}
- cubeb_stream_params * params =
- input_stream_params ? input_stream_params : output_stream_params;
+ cubeb_stream_params * params = input_stream_params ?
+ input_stream_params : output_stream_params;
switch (params->format) {
case CUBEB_SAMPLE_S16LE:
@@ -132,6 +99,8 @@ validate_stream_params(cubeb_stream_params * input_stream_params,
return CUBEB_ERROR_INVALID_FORMAT;
}
+
+
static int
validate_latency(int latency)
{
@@ -142,104 +111,18 @@ validate_latency(int latency)
}
int
-cubeb_init(cubeb ** context, char const * context_name,
- char const * backend_name)
+cubeb_init(cubeb ** context, char const * context_name)
{
- int (*init_oneshot)(cubeb **, char const *) = NULL;
-
- if (backend_name != NULL) {
- if (!strcmp(backend_name, "pulse")) {
-#if defined(USE_PULSE)
- init_oneshot = pulse_init;
-#endif
- } else if (!strcmp(backend_name, "pulse-rust")) {
-#if defined(USE_PULSE_RUST)
- init_oneshot = pulse_rust_init;
-#endif
- } else if (!strcmp(backend_name, "jack")) {
+ int (* init[])(cubeb **, char const *) = {
#if defined(USE_JACK)
- init_oneshot = jack_init;
-#endif
- } else if (!strcmp(backend_name, "alsa")) {
-#if defined(USE_ALSA)
- init_oneshot = alsa_init;
-#endif
- } else if (!strcmp(backend_name, "audiounit")) {
-#if defined(USE_AUDIOUNIT)
- init_oneshot = audiounit_init;
-#endif
- } else if (!strcmp(backend_name, "audiounit-rust")) {
-#if defined(USE_AUDIOUNIT_RUST)
- init_oneshot = audiounit_rust_init;
-#endif
- } else if (!strcmp(backend_name, "wasapi")) {
-#if defined(USE_WASAPI)
- init_oneshot = wasapi_init;
-#endif
- } else if (!strcmp(backend_name, "winmm")) {
-#if defined(USE_WINMM)
- init_oneshot = winmm_init;
-#endif
- } else if (!strcmp(backend_name, "sndio")) {
-#if defined(USE_SNDIO)
- init_oneshot = sndio_init;
-#endif
- } else if (!strcmp(backend_name, "sun")) {
-#if defined(USE_SUN)
- init_oneshot = sun_init;
-#endif
- } else if (!strcmp(backend_name, "opensl")) {
-#if defined(USE_OPENSL)
- init_oneshot = opensl_init;
-#endif
- } else if (!strcmp(backend_name, "oss")) {
-#if defined(USE_OSS)
- init_oneshot = oss_init;
-#endif
- } else if (!strcmp(backend_name, "aaudio")) {
-#if defined(USE_AAUDIO)
- init_oneshot = aaudio_init;
-#endif
- } else if (!strcmp(backend_name, "audiotrack")) {
-#if defined(USE_AUDIOTRACK)
- init_oneshot = audiotrack_init;
-#endif
- } else if (!strcmp(backend_name, "kai")) {
-#if defined(USE_KAI)
- init_oneshot = kai_init;
-#endif
- } else {
- /* Already set */
- }
- }
-
- int (*default_init[])(cubeb **, char const *) = {
- /*
- * init_oneshot must be at the top to allow user
- * to override all other choices
- */
- init_oneshot,
-#if defined(USE_PULSE_RUST)
- pulse_rust_init,
+ jack_init,
#endif
#if defined(USE_PULSE)
pulse_init,
#endif
-#if defined(USE_JACK)
- jack_init,
-#endif
-#if defined(USE_SNDIO)
- sndio_init,
-#endif
#if defined(USE_ALSA)
alsa_init,
#endif
-#if defined(USE_OSS)
- oss_init,
-#endif
-#if defined(USE_AUDIOUNIT_RUST)
- audiounit_rust_init,
-#endif
#if defined(USE_AUDIOUNIT)
audiounit_init,
#endif
@@ -249,23 +132,21 @@ cubeb_init(cubeb ** context, char const * context_name,
#if defined(USE_WINMM)
winmm_init,
#endif
-#if defined(USE_SUN)
- sun_init,
+#if defined(USE_SNDIO)
+ sndio_init,
#endif
#if defined(USE_OPENSL)
opensl_init,
#endif
- // TODO: should probably be preferred over OpenSLES when available.
- // Initialization will fail on old android devices.
-#if defined(USE_AAUDIO)
- aaudio_init,
-#endif
#if defined(USE_AUDIOTRACK)
audiotrack_init,
#endif
#if defined(USE_KAI)
kai_init,
#endif
+#if defined(USE_SUN)
+ sunaudio_init,
+#endif
};
int i;
@@ -273,10 +154,10 @@ cubeb_init(cubeb ** context, char const * context_name,
return CUBEB_ERROR_INVALID_PARAMETER;
}
-#define OK(fn) assert((*context)->ops->fn)
- for (i = 0; i < NELEMS(default_init); ++i) {
- if (default_init[i] && default_init[i](context, context_name) == CUBEB_OK) {
+ 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);
@@ -287,6 +168,7 @@ cubeb_init(cubeb ** context, char const * context_name,
return CUBEB_OK;
}
}
+
return CUBEB_ERROR;
}
@@ -315,10 +197,9 @@ cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels)
}
int
-cubeb_get_min_latency(cubeb * context, cubeb_stream_params * params,
- uint32_t * latency_ms)
+cubeb_get_min_latency(cubeb * context, cubeb_stream_params params, uint32_t * latency_ms)
{
- if (!context || !params || !latency_ms) {
+ if (!context || !latency_ms) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
@@ -326,7 +207,7 @@ cubeb_get_min_latency(cubeb * context, cubeb_stream_params * params,
return CUBEB_ERROR_NOT_SUPPORTED;
}
- return context->ops->get_min_latency(context, *params, latency_ms);
+ return context->ops->get_min_latency(context, params, latency_ms);
}
int
@@ -354,39 +235,36 @@ cubeb_destroy(cubeb * context)
}
int
-cubeb_stream_init(cubeb * context, cubeb_stream ** stream,
- char const * stream_name, cubeb_devid input_device,
+cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
+ cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
- unsigned int latency, cubeb_data_callback data_callback,
- cubeb_state_callback state_callback, void * user_ptr)
+ unsigned int latency,
+ cubeb_data_callback data_callback,
+ cubeb_state_callback state_callback,
+ void * user_ptr)
{
int r;
- if (!context || !stream || !data_callback || !state_callback) {
+ if (!context || !stream) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
- if ((r = validate_stream_params(input_stream_params, output_stream_params)) !=
- CUBEB_OK ||
+ if ((r = validate_stream_params(input_stream_params, output_stream_params)) != CUBEB_OK ||
(r = validate_latency(latency)) != CUBEB_OK) {
return r;
}
- r = context->ops->stream_init(context, stream, stream_name, input_device,
- input_stream_params, output_device,
- output_stream_params, latency, data_callback,
- state_callback, user_ptr);
-
- if (r == CUBEB_ERROR_INVALID_FORMAT) {
- LOG("Invalid format, %p %p %d %d", output_stream_params,
- input_stream_params,
- output_stream_params && output_stream_params->format,
- input_stream_params && input_stream_params->format);
- }
-
- return r;
+ return context->ops->stream_init(context, stream, stream_name,
+ input_device,
+ input_stream_params,
+ output_device,
+ output_stream_params,
+ latency,
+ data_callback,
+ state_callback,
+ user_ptr);
}
void
@@ -444,20 +322,6 @@ cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
}
int
-cubeb_stream_get_input_latency(cubeb_stream * stream, uint32_t * latency)
-{
- if (!stream || !latency) {
- return CUBEB_ERROR_INVALID_PARAMETER;
- }
-
- if (!stream->context->ops->stream_get_input_latency) {
- return CUBEB_ERROR_NOT_SUPPORTED;
- }
-
- return stream->context->ops->stream_get_input_latency(stream, latency);
-}
-
-int
cubeb_stream_set_volume(cubeb_stream * stream, float volume)
{
if (!stream || volume > 1.0 || volume < 0.0) {
@@ -471,23 +335,21 @@ cubeb_stream_set_volume(cubeb_stream * stream, float volume)
return stream->context->ops->stream_set_volume(stream, volume);
}
-int
-cubeb_stream_set_name(cubeb_stream * stream, char const * stream_name)
+int cubeb_stream_set_panning(cubeb_stream * stream, float panning)
{
- if (!stream || !stream_name) {
+ if (!stream || panning < -1.0 || panning > 1.0) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
- if (!stream->context->ops->stream_set_name) {
+ if (!stream->context->ops->stream_set_panning) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
- return stream->context->ops->stream_set_name(stream, stream_name);
+ return stream->context->ops->stream_set_panning(stream, panning);
}
-int
-cubeb_stream_get_current_device(cubeb_stream * stream,
- cubeb_device ** const device)
+int cubeb_stream_get_current_device(cubeb_stream * stream,
+ cubeb_device ** const device)
{
if (!stream || !device) {
return CUBEB_ERROR_INVALID_PARAMETER;
@@ -500,8 +362,8 @@ cubeb_stream_get_current_device(cubeb_stream * stream,
return stream->context->ops->stream_get_current_device(stream, device);
}
-int
-cubeb_stream_device_destroy(cubeb_stream * stream, cubeb_device * device)
+int cubeb_stream_device_destroy(cubeb_stream * stream,
+ cubeb_device * device)
{
if (!stream || !device) {
return CUBEB_ERROR_INVALID_PARAMETER;
@@ -514,10 +376,8 @@ cubeb_stream_device_destroy(cubeb_stream * stream, cubeb_device * device)
return stream->context->ops->stream_device_destroy(stream, device);
}
-int
-cubeb_stream_register_device_changed_callback(
- cubeb_stream * stream,
- cubeb_device_changed_callback device_changed_callback)
+int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
+ cubeb_device_changed_callback device_changed_callback)
{
if (!stream) {
return CUBEB_ERROR_INVALID_PARAMETER;
@@ -527,70 +387,59 @@ cubeb_stream_register_device_changed_callback(
return CUBEB_ERROR_NOT_SUPPORTED;
}
- return stream->context->ops->stream_register_device_changed_callback(
- stream, device_changed_callback);
+ return stream->context->ops->stream_register_device_changed_callback(stream, device_changed_callback);
}
-void *
-cubeb_stream_user_ptr(cubeb_stream * stream)
-{
- if (!stream) {
- return NULL;
- }
-
- return stream->user_ptr;
-}
-
-static void
-log_device(cubeb_device_info * device_info)
+static
+void log_device(cubeb_device_info * device_info)
{
char devfmts[128] = "";
- const char *devtype, *devstate, *devdeffmt;
+ const char * devtype, * devstate, * devdeffmt;
switch (device_info->type) {
- case CUBEB_DEVICE_TYPE_INPUT:
- devtype = "input";
- break;
- case CUBEB_DEVICE_TYPE_OUTPUT:
- devtype = "output";
- break;
- case CUBEB_DEVICE_TYPE_UNKNOWN:
- default:
- devtype = "unknown?";
- break;
+ case CUBEB_DEVICE_TYPE_INPUT:
+ devtype = "input";
+ break;
+ case CUBEB_DEVICE_TYPE_OUTPUT:
+ devtype = "output";
+ break;
+ case CUBEB_DEVICE_TYPE_UNKNOWN:
+ default:
+ devtype = "unknown?";
+ break;
};
switch (device_info->state) {
- case CUBEB_DEVICE_STATE_DISABLED:
- devstate = "disabled";
- break;
- case CUBEB_DEVICE_STATE_UNPLUGGED:
- devstate = "unplugged";
- break;
- case CUBEB_DEVICE_STATE_ENABLED:
- devstate = "enabled";
- break;
- default:
- devstate = "unknown?";
- break;
+ case CUBEB_DEVICE_STATE_DISABLED:
+ devstate = "disabled";
+ break;
+ case CUBEB_DEVICE_STATE_UNPLUGGED:
+ devstate = "unplugged";
+ break;
+ case CUBEB_DEVICE_STATE_ENABLED:
+ devstate = "enabled";
+ break;
+ default:
+ devstate = "unknown?";
+ break;
};
switch (device_info->default_format) {
- case CUBEB_DEVICE_FMT_S16LE:
- devdeffmt = "S16LE";
- break;
- case CUBEB_DEVICE_FMT_S16BE:
- devdeffmt = "S16BE";
- break;
- case CUBEB_DEVICE_FMT_F32LE:
- devdeffmt = "F32LE";
- break;
- case CUBEB_DEVICE_FMT_F32BE:
- devdeffmt = "F32BE";
- break;
- default:
- devdeffmt = "unknown?";
- break;
+ case CUBEB_DEVICE_FMT_S16LE:
+ devdeffmt = "S16LE";
+ break;
+ case CUBEB_DEVICE_FMT_S16BE:
+ devdeffmt = "S16BE";
+ break;
+ case CUBEB_DEVICE_FMT_F32LE:
+ devdeffmt = "F32LE";
+ break;
+ case CUBEB_DEVICE_FMT_F32BE:
+ devdeffmt = "F32BE";
+ break;
+ default:
+ devdeffmt = "unknown?";
+ break;
};
if (device_info->format & CUBEB_DEVICE_FMT_S16LE) {
@@ -617,17 +466,20 @@ log_device(cubeb_device_info * device_info)
"\tRate:\t[%u, %u] (default: %u)\n"
"\tLatency: lo %u frames, hi %u frames",
device_info->device_id, device_info->preferred ? " (PREFERRED)" : "",
- device_info->friendly_name, device_info->group_id,
- device_info->vendor_name, devtype, devstate, device_info->max_channels,
- (devfmts[0] == '\0') ? devfmts : devfmts + 1,
- (unsigned int)device_info->format, devdeffmt, device_info->min_rate,
- device_info->max_rate, device_info->default_rate, device_info->latency_lo,
- device_info->latency_hi);
+ device_info->friendly_name,
+ device_info->group_id,
+ device_info->vendor_name,
+ devtype,
+ devstate,
+ device_info->max_channels,
+ (devfmts[0] == '\0') ? devfmts : devfmts + 1, (unsigned int)device_info->format, devdeffmt,
+ device_info->min_rate, device_info->max_rate, device_info->default_rate,
+ device_info->latency_lo, device_info->latency_hi);
}
-int
-cubeb_enumerate_devices(cubeb * context, cubeb_device_type devtype,
- cubeb_device_collection * collection)
+int cubeb_enumerate_devices(cubeb * context,
+ cubeb_device_type devtype,
+ cubeb_device_collection ** collection)
{
int rv;
if ((devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
@@ -639,59 +491,61 @@ cubeb_enumerate_devices(cubeb * context, cubeb_device_type devtype,
rv = context->ops->enumerate_devices(context, devtype, collection);
- if (g_cubeb_log_callback) {
- for (size_t i = 0; i < collection->count; i++) {
- log_device(&collection->device[i]);
+ if (g_log_callback) {
+ for (uint32_t i = 0; i < (*collection)->count; i++) {
+ log_device((*collection)->device[i]);
}
}
return rv;
}
-int
-cubeb_device_collection_destroy(cubeb * context,
- cubeb_device_collection * collection)
+int cubeb_device_collection_destroy(cubeb_device_collection * collection)
{
- int r;
+ uint32_t i;
- if (context == NULL || collection == NULL)
+ if (collection == NULL)
return CUBEB_ERROR_INVALID_PARAMETER;
- if (!context->ops->device_collection_destroy)
- return CUBEB_ERROR_NOT_SUPPORTED;
+ for (i = 0; i < collection->count; i++)
+ cubeb_device_info_destroy(collection->device[i]);
- if (!collection->device)
- return CUBEB_OK;
+ free(collection);
+ return CUBEB_OK;
+}
- r = context->ops->device_collection_destroy(context, collection);
- if (r == CUBEB_OK) {
- collection->device = NULL;
- collection->count = 0;
+int cubeb_device_info_destroy(cubeb_device_info * info)
+{
+ if (info == NULL) {
+ return CUBEB_ERROR_INVALID_PARAMETER;
}
- return r;
+ free(info->device_id);
+ free(info->friendly_name);
+ free(info->group_id);
+ free(info->vendor_name);
+
+ free(info);
+ return CUBEB_OK;
}
-int
-cubeb_register_device_collection_changed(
- cubeb * context, cubeb_device_type devtype,
- cubeb_device_collection_changed_callback callback, void * user_ptr)
+int cubeb_register_device_collection_changed(cubeb * context,
+ cubeb_device_type devtype,
+ cubeb_device_collection_changed_callback callback,
+ void * user_ptr)
{
- if (context == NULL ||
- (devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
+ if (context == NULL || (devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
return CUBEB_ERROR_INVALID_PARAMETER;
if (!context->ops->register_device_collection_changed) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
- return context->ops->register_device_collection_changed(context, devtype,
- callback, user_ptr);
+ return context->ops->register_device_collection_changed(context, devtype, callback, user_ptr);
}
-int
-cubeb_set_log_callback(cubeb_log_level log_level,
- cubeb_log_callback log_callback)
+int cubeb_set_log_callback(cubeb_log_level log_level,
+ cubeb_log_callback log_callback)
{
if (log_level < CUBEB_LOG_DISABLED || log_level > CUBEB_LOG_VERBOSE) {
return CUBEB_ERROR_INVALID_FORMAT;
@@ -701,21 +555,20 @@ cubeb_set_log_callback(cubeb_log_level log_level,
return CUBEB_ERROR_INVALID_PARAMETER;
}
- if (g_cubeb_log_callback && log_callback) {
+ if (g_log_callback && log_callback) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
- g_cubeb_log_callback = log_callback;
- g_cubeb_log_level = log_level;
-
- // Logging a message here allows to initialize the asynchronous logger from a
- // thread that is not the audio rendering thread, and especially to not
- // initialize it the first time we find a verbose log, which is often in the
- // audio rendering callback, that runs from the audio rendering thread, and
- // that is high priority, and that we don't want to block.
- if (log_level >= CUBEB_LOG_VERBOSE) {
- ALOGV("Starting cubeb log");
- }
+ g_log_callback = log_callback;
+ g_log_level = log_level;
return CUBEB_OK;
}
+
+void
+cubeb_crash()
+{
+ *((volatile int *) NULL) = 0;
+ abort();
+}
+