diff --git a/include/cubeb/cubeb.h b/include/cubeb/cubeb.h
index d1db0c9..9bc06fb 100644
--- a/include/cubeb/cubeb.h
+++ b/include/cubeb/cubeb.h
@@ -19,44 +19,86 @@ extern "C" {
This is the documentation for the libcubeb C API.
libcubeb is a callback-based audio API library allowing the
- authoring of portable multiplatform audio playback.
+ authoring of portable multiplatform audio playback and recording.
@section example Example code
+ This example shows how to create a duplex stream that pipes the microphone
+ to the speakers, with minimal latency and the proper sample-rate for the
+ platform.
+
@code
cubeb * app_ctx;
cubeb_init(&app_ctx, "Example Application");
+ int rv;
+ int rate;
+ int latency_ms;
+ uint64_t ts;
- cubeb_stream_params params;
- params.format = CUBEB_SAMPLE_S16NE;
- params.rate = 48000;
- params.channels = 2;
+ rv = cubeb_get_min_latency(app_ctx, output_params, &latency_ms);
+ if (rv != CUBEB_OK) {
+ fprintf(stderr, "Could not get minimum latency");
+ return rv;
+ }
- unsigned int latency_ms = 250;
+ rv = cubeb_get_preferred_sample_rate(app_ctx, output_params, &rate);
+ if (rv != CUBEB_OK) {
+ fprintf(stderr, "Could not get preferred sample-rate");
+ return rv;
+ }
+
+ cubeb_stream_params output_params;
+ output_params.format = CUBEB_SAMPLE_FLOAT32NE;
+ output_params.rate = rate;
+ output_params.channels = 2;
+
+ cubeb_stream_params input_params;
+ output_params.format = CUBEB_SAMPLE_FLOAT32NE;
+ output_params.rate = rate;
+ output_params.channels = 1;
cubeb_stream * stm;
- cubeb_stream_init(app_ctx, &stm, "Example Stream 1", params,
- latency_ms, data_cb, state_cb, NULL);
+ rv = cubeb_stream_init(app_ctx, &stm, "Example Stream 1",
+ NULL, input_params,
+ NULL, output_params,
+ latency_ms,
+ data_cb, state_cb,
+ NULL);
+ if (rv != CUBEB_OK) {
+ fprintf(stderr, "Could not open the stream");
+ return rv;
+ }
- cubeb_stream_start(stm);
+ rv = cubeb_stream_start(stm);
+ if (rv != CUBEB_OK) {
+ fprintf(stderr, "Could not start the stream");
+ return rv;
+ }
for (;;) {
cubeb_stream_get_position(stm, &ts);
printf("time=%llu\n", ts);
sleep(1);
}
- cubeb_stream_stop(stm);
+ rv = cubeb_stream_stop(stm);
+ if (rv != CUBEB_OK) {
+ fprintf(stderr, "Could not stop the stream");
+ return rv;
+ }
cubeb_stream_destroy(stm);
cubeb_destroy(app_ctx);
@endcode
@code
- long data_cb(cubeb_stream * stm, void * user, void * buffer, long nframes)
+ long data_cb(cubeb_stream * stm, void * user,
+ void * input_buffer, void * output_buffer, long nframes)
{
- short * buf = buffer;
+ float * in = input_buffer;
+ float * out = output_buffer;
+
for (i = 0; i < nframes; ++i) {
- for (c = 0; c < params.channels; ++c) {
- buf[i][c] = 0;
+ for (c = 0; c < 2; ++c) {
+ buf[i][c] = in[i];
}
}
return nframes;
@@ -101,6 +143,10 @@ typedef enum {
} cubeb_sample_format;
#if defined(__ANDROID__)
+/**
+ * This maps to the underlying stream types on supported platforms, e.g.
+ * Android.
+ */
typedef enum {
CUBEB_STREAM_TYPE_VOICE_CALL = 0,
CUBEB_STREAM_TYPE_SYSTEM = 1,
@@ -133,7 +179,7 @@ typedef struct {
#endif
} cubeb_stream_params;
-/** Output device description */
+/** Audio device description */
typedef struct {
char * output_name; /**< The name of the output device */
char * input_name; /**< The name of the input device */
@@ -249,15 +295,21 @@ typedef struct {
} cubeb_device_collection;
/** User supplied data callback.
- @param stream The stream for which this callback fired
- @param user_ptr The pointer passed to cubeb_stream_create
+ - Calling other cubeb functions from this callback is unsafe.
+ - The code in the callback should be non-blocking.
+ - Returning less than the number of frames this callback asks for or
+ provides puts the stream in drain mode. This callback will not be called
+ again, and the state callback will be called with CUBEB_STATE_DRAINED when
+ all the frames have been output.
+ @param stream The stream for which this callback fired.
+ @param user_ptr The pointer passed to cubeb_stream_init.
@param input_buffer A pointer containing the input data, or nullptr
if this is an output-only stream.
- @param output_buffer A pointer containing the output data, or nullptr
- if this is an input -only stream.
+ @param output_buffer A pointer to a buffer to be filled with audio samples,
+ or nullptr if this is an input-only stream.
@param nframes The number of frames of the two buffer.
- @retval Number of frames written to the output buffer, which must equal
- nframes except at end of stream.
+ @retval Number of frames written to the output buffer. If this number is
+ less than nframes, then the stream will start to drain.
@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,
@@ -267,39 +319,43 @@ typedef long (* cubeb_data_callback)(cubeb_stream * stream,
long nframes);
/** User supplied state callback.
- @param stream
- @param user_ptr
- @param state */
+ @param stream The stream for this this callback fired.
+ @param user_ptr The pointer passed to cubeb_stream_init.
+ @param state The new state of the stream. */
typedef void (* cubeb_state_callback)(cubeb_stream * stream,
void * user_ptr,
cubeb_state state);
/**
* User supplied callback called when the underlying device changed.
- * @param user */
+ * @param user The pointer passed to cubeb_stream_init. */
typedef void (* cubeb_device_changed_callback)(void * user_ptr);
/**
* User supplied callback called when the underlying device collection changed.
- * @param context
- * @param user_ptr */
-typedef void (* cubeb_device_collection_changed_callback)(cubeb * context, void * user_ptr);
+ * @param context A pointer to the cubeb context.
+ * @param user_ptr The pointer passed to cubeb_stream_init. */
+typedef void (* cubeb_device_collection_changed_callback)(cubeb * context,
+ void * user_ptr);
/** Initialize an application context. This will perform any library or
application scoped initialization.
- @param context
- @param context_name
- @retval CUBEB_OK
- @retval CUBEB_ERROR */
+ @param context A out param where an opaque pointer to the application
+ context will be returned.
+ @param context_name A name for the context. Depending on the platform this
+ can appear in different locations.
+ @retval CUBEB_OK in case of success.
+ @retval CUBEB_ERROR in case of error, for example because the host
+ has no audio hardware. */
int cubeb_init(cubeb ** context, char const * context_name);
/** Get a read-only string identifying this context's current backend.
- @param context
+ @param context A pointer to the cubeb context.
@retval Read-only string identifying current backend. */
char const * cubeb_get_backend_id(cubeb * context);
/** Get the maximum possible number of channels.
- @param context
+ @param context A pointer to the cubeb context.
@param max_channels The maximum number of channels.
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER
@@ -308,9 +364,9 @@ char const * cubeb_get_backend_id(cubeb * context);
int cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels);
/** Get the minimal latency value, in milliseconds, that is guaranteed to work
- when creating a stream for the specified sample rate. This is platform and
- backend dependant.
- @param context
+ when creating a stream for the specified sample rate. This is platform,
+ hardware and backend dependant.
+ @param context A pointer to the cubeb context.
@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.
@@ -323,26 +379,28 @@ int cubeb_get_min_latency(cubeb * context,
/** 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 context A pointer to the cubeb 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.
- @param context */
+/** Destroy an application context. This must be called after all stream have
+ * been destroyed.
+ @param context A pointer to the cubeb context.*/
void cubeb_destroy(cubeb * context);
/** Initialize a stream associated with the supplied application context.
- @param context
- @param stream
- @param stream_name
- @param input_device Device for the input side of the stream. If NULL
+ @param context A pointer to the cubeb context.
+ @param stream An out parameter to be filled with the an opaque pointer to a
+ cubeb stream.
+ @param stream_name A name for this stream.
+ @param input_device Device for the input side of the stream. If NULL the
default input device is used.
@param input_stream_params Parameters for the input side of the stream, or
NULL if this stream is output only.
- @param output_device Device for the output side of the stream. If NULL
+ @param output_device Device for the output side of the stream. If NULL the
default output device is used.
@param output_stream_params Parameters for the output side of the stream, or
NULL if this stream is input only.
@@ -350,8 +408,9 @@ void cubeb_destroy(cubeb * context);
is [1, 2000].
@param data_callback Will be called to preroll data before playback is
started by cubeb_stream_start.
- @param state_callback
- @param user_ptr
+ @param state_callback A pointer to a state callback.
+ @param user_ptr A pointer that will be passed to the callbacks. This pointer
+ must outlive the life time of the stream.
@retval CUBEB_OK
@retval CUBEB_ERROR
@retval CUBEB_ERROR_INVALID_FORMAT
@@ -368,8 +427,9 @@ int cubeb_stream_init(cubeb * context,
cubeb_state_callback state_callback,
void * user_ptr);
-/** Destroy a stream.
- @param stream */
+/** Destroy a stream. `cubeb_stream_stop` MUST be called before destroying a
+ stream.
+ @param stream The stream to destroy. */
void cubeb_stream_destroy(cubeb_stream * stream);
/** Start playback.