1 /*
2  * Copyright © 2011 Mozilla Foundation
3  *
4  * This program is made available under an ISC-style license.  See the
5  * accompanying file LICENSE for details.
6  */
7 #if !defined(CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382)
8 #define CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382
9 
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include "cubeb_export.h"
13 
14 #if defined(__cplusplus)
15 extern "C" {
16 #endif
17 
18 /** @mainpage
19 
20     @section intro Introduction
21 
22     This is the documentation for the <tt>libcubeb</tt> C API.
23     <tt>libcubeb</tt> is a callback-based audio API library allowing the
24     authoring of portable multiplatform audio playback and recording.
25 
26     @section example Example code
27 
28     This example shows how to create a duplex stream that pipes the microphone
29     to the speakers, with minimal latency and the proper sample-rate for the
30     platform.
31 
32     @code
33     cubeb * app_ctx;
34     cubeb_init(&app_ctx, "Example Application", NULL);
35     int rv;
36     uint32_t rate;
37     uint32_t latency_frames;
38     uint64_t ts;
39 
40     rv = cubeb_get_preferred_sample_rate(app_ctx, &rate);
41     if (rv != CUBEB_OK) {
42       fprintf(stderr, "Could not get preferred sample-rate");
43       return rv;
44     }
45 
46     cubeb_stream_params output_params;
47     output_params.format = CUBEB_SAMPLE_FLOAT32NE;
48     output_params.rate = rate;
49     output_params.channels = 2;
50     output_params.layout = CUBEB_LAYOUT_UNDEFINED;
51     output_params.prefs = CUBEB_STREAM_PREF_NONE;
52 
53     rv = cubeb_get_min_latency(app_ctx, &output_params, &latency_frames);
54     if (rv != CUBEB_OK) {
55       fprintf(stderr, "Could not get minimum latency");
56       return rv;
57     }
58 
59     cubeb_stream_params input_params;
60     input_params.format = CUBEB_SAMPLE_FLOAT32NE;
61     input_params.rate = rate;
62     input_params.channels = 1;
63     input_params.layout = CUBEB_LAYOUT_UNDEFINED;
64     input_params.prefs = CUBEB_STREAM_PREF_NONE;
65 
66     cubeb_stream * stm;
67     rv = cubeb_stream_init(app_ctx, &stm, "Example Stream 1",
68                            NULL, &input_params,
69                            NULL, &output_params,
70                            latency_frames,
71                            data_cb, state_cb,
72                            NULL);
73     if (rv != CUBEB_OK) {
74       fprintf(stderr, "Could not open the stream");
75       return rv;
76     }
77 
78     rv = cubeb_stream_start(stm);
79     if (rv != CUBEB_OK) {
80       fprintf(stderr, "Could not start the stream");
81       return rv;
82     }
83     for (;;) {
84       cubeb_stream_get_position(stm, &ts);
85       printf("time=%llu\n", ts);
86       sleep(1);
87     }
88     rv = cubeb_stream_stop(stm);
89     if (rv != CUBEB_OK) {
90       fprintf(stderr, "Could not stop the stream");
91       return rv;
92     }
93 
94     cubeb_stream_destroy(stm);
95     cubeb_destroy(app_ctx);
96     @endcode
97 
98     @code
99     long data_cb(cubeb_stream * stm, void * user,
100                  const void * input_buffer, void * output_buffer, long nframes)
101     {
102       const float * in  = input_buffer;
103       float * out = output_buffer;
104 
105       for (int i = 0; i < nframes; ++i) {
106         for (int c = 0; c < 2; ++c) {
107           out[2 * i + c] = in[i];
108         }
109       }
110       return nframes;
111     }
112     @endcode
113 
114     @code
115     void state_cb(cubeb_stream * stm, void * user, cubeb_state state)
116     {
117       printf("state=%d\n", state);
118     }
119     @endcode
120 */
121 
122 /** @file
123     The <tt>libcubeb</tt> C API. */
124 
125 typedef struct cubeb cubeb;               /**< Opaque handle referencing the application state. */
126 typedef struct cubeb_stream cubeb_stream; /**< Opaque handle referencing the stream state. */
127 
128 /** Sample format enumeration. */
129 typedef enum {
130   /**< Little endian 16-bit signed PCM. */
131   CUBEB_SAMPLE_S16LE,
132   /**< Big endian 16-bit signed PCM. */
133   CUBEB_SAMPLE_S16BE,
134   /**< Little endian 32-bit IEEE floating point PCM. */
135   CUBEB_SAMPLE_FLOAT32LE,
136   /**< Big endian 32-bit IEEE floating point PCM. */
137   CUBEB_SAMPLE_FLOAT32BE,
138 #if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__)
139   /**< Native endian 16-bit signed PCM. */
140   CUBEB_SAMPLE_S16NE = CUBEB_SAMPLE_S16BE,
141   /**< Native endian 32-bit IEEE floating point PCM. */
142   CUBEB_SAMPLE_FLOAT32NE = CUBEB_SAMPLE_FLOAT32BE
143 #else
144   /**< Native endian 16-bit signed PCM. */
145   CUBEB_SAMPLE_S16NE = CUBEB_SAMPLE_S16LE,
146   /**< Native endian 32-bit IEEE floating point PCM. */
147   CUBEB_SAMPLE_FLOAT32NE = CUBEB_SAMPLE_FLOAT32LE
148 #endif
149 } cubeb_sample_format;
150 
151 /** An opaque handle used to refer a particular input or output device
152  *  across calls. */
153 typedef void const * cubeb_devid;
154 
155 /** Level (verbosity) of logging for a particular cubeb context. */
156 typedef enum {
157   CUBEB_LOG_DISABLED = 0, /** < Logging disabled */
158   CUBEB_LOG_NORMAL = 1, /**< Logging lifetime operation (creation/destruction). */
159   CUBEB_LOG_VERBOSE = 2, /**< Verbose logging of callbacks, can have performance implications. */
160 } cubeb_log_level;
161 
162 typedef enum {
163   CHANNEL_UNKNOWN = 0,
164   CHANNEL_FRONT_LEFT = 1 << 0,
165   CHANNEL_FRONT_RIGHT = 1 << 1,
166   CHANNEL_FRONT_CENTER = 1 << 2,
167   CHANNEL_LOW_FREQUENCY = 1 << 3,
168   CHANNEL_BACK_LEFT = 1 << 4,
169   CHANNEL_BACK_RIGHT = 1 << 5,
170   CHANNEL_FRONT_LEFT_OF_CENTER = 1 << 6,
171   CHANNEL_FRONT_RIGHT_OF_CENTER = 1 << 7,
172   CHANNEL_BACK_CENTER = 1 << 8,
173   CHANNEL_SIDE_LEFT = 1 << 9,
174   CHANNEL_SIDE_RIGHT = 1 << 10,
175   CHANNEL_TOP_CENTER = 1 << 11,
176   CHANNEL_TOP_FRONT_LEFT = 1 << 12,
177   CHANNEL_TOP_FRONT_CENTER = 1 << 13,
178   CHANNEL_TOP_FRONT_RIGHT = 1 << 14,
179   CHANNEL_TOP_BACK_LEFT = 1 << 15,
180   CHANNEL_TOP_BACK_CENTER = 1 << 16,
181   CHANNEL_TOP_BACK_RIGHT = 1 << 17
182 } cubeb_channel;
183 
184 typedef uint32_t cubeb_channel_layout;
185 // Some common layout definitions.
186 enum {
187   CUBEB_LAYOUT_UNDEFINED = 0, // Indicate the speaker's layout is undefined.
188   CUBEB_LAYOUT_MONO = CHANNEL_FRONT_CENTER,
189   CUBEB_LAYOUT_MONO_LFE = CUBEB_LAYOUT_MONO | CHANNEL_LOW_FREQUENCY,
190   CUBEB_LAYOUT_STEREO = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT,
191   CUBEB_LAYOUT_STEREO_LFE = CUBEB_LAYOUT_STEREO | CHANNEL_LOW_FREQUENCY,
192   CUBEB_LAYOUT_3F =
193     CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER,
194   CUBEB_LAYOUT_3F_LFE = CUBEB_LAYOUT_3F | CHANNEL_LOW_FREQUENCY,
195   CUBEB_LAYOUT_2F1 =
196     CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_BACK_CENTER,
197   CUBEB_LAYOUT_2F1_LFE = CUBEB_LAYOUT_2F1 | CHANNEL_LOW_FREQUENCY,
198   CUBEB_LAYOUT_3F1 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
199                      CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER,
200   CUBEB_LAYOUT_3F1_LFE = CUBEB_LAYOUT_3F1 | CHANNEL_LOW_FREQUENCY,
201   CUBEB_LAYOUT_2F2 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
202                      CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
203   CUBEB_LAYOUT_2F2_LFE = CUBEB_LAYOUT_2F2 | CHANNEL_LOW_FREQUENCY,
204   CUBEB_LAYOUT_QUAD = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
205                       CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT,
206   CUBEB_LAYOUT_QUAD_LFE = CUBEB_LAYOUT_QUAD | CHANNEL_LOW_FREQUENCY,
207   CUBEB_LAYOUT_3F2 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
208                      CHANNEL_FRONT_CENTER | CHANNEL_SIDE_LEFT |
209                      CHANNEL_SIDE_RIGHT,
210   CUBEB_LAYOUT_3F2_LFE = CUBEB_LAYOUT_3F2 | CHANNEL_LOW_FREQUENCY,
211   CUBEB_LAYOUT_3F2_BACK = CUBEB_LAYOUT_QUAD | CHANNEL_FRONT_CENTER,
212   CUBEB_LAYOUT_3F2_LFE_BACK = CUBEB_LAYOUT_3F2_BACK | CHANNEL_LOW_FREQUENCY,
213   CUBEB_LAYOUT_3F3R_LFE = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
214                           CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
215                           CHANNEL_BACK_CENTER | CHANNEL_SIDE_LEFT |
216                           CHANNEL_SIDE_RIGHT,
217   CUBEB_LAYOUT_3F4_LFE = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
218                          CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
219                          CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
220                          CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
221 };
222 
223 /** Miscellaneous stream preferences. */
224 typedef enum {
225   CUBEB_STREAM_PREF_NONE     = 0x00, /**< No stream preferences are requested. */
226   CUBEB_STREAM_PREF_LOOPBACK = 0x01, /**< Request a loopback stream. Should be
227                                          specified on the input params and an
228                                          output device to loopback from should
229                                          be passed in place of an input device. */
230   CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
231                                                           default device on OS
232                                                           changes. */
233   CUBEB_STREAM_PREF_VOICE = 0x04, /**< This stream is going to transport voice data.
234                                        Depending on the backend and platform, this can
235                                        change the audio input or output devices
236                                        selected, as well as the quality of the stream,
237                                        for example to accomodate bluetooth SCO modes on
238                                        bluetooth devices. */
239   CUBEB_STREAM_PREF_RAW = 0x08, /**< Windows only. Bypass all signal processing
240                                      except for always on APO, driver and hardware. */
241   CUBEB_STREAM_PREF_PERSIST = 0x10, /**< Request that the volume and mute settings
242                                          should persist across restarts of the stream
243                                          and/or application. May not be honored for
244                                          all backends and platforms. */
245 
246   CUBEB_STREAM_PREF_JACK_NO_AUTO_CONNECT = 0x20  /**< Don't automatically try to connect
247                                                       ports.  Only affects the jack
248                                                       backend. */
249 } cubeb_stream_prefs;
250 
251 /** Stream format initialization parameters. */
252 typedef struct {
253   cubeb_sample_format format;   /**< Requested sample format.  One of
254                                      #cubeb_sample_format. */
255   uint32_t rate;                /**< Requested sample rate.  Valid range is [1000, 192000]. */
256   uint32_t channels;            /**< Requested channel count.  Valid range is [1, 8]. */
257   cubeb_channel_layout layout;  /**< Requested channel layout. This must be consistent with the provided channels. CUBEB_LAYOUT_UNDEFINED if unknown */
258   cubeb_stream_prefs prefs;     /**< Requested preferences. */
259 } cubeb_stream_params;
260 
261 /** Audio device description */
262 typedef struct {
263   char * output_name; /**< The name of the output device */
264   char * input_name; /**< The name of the input device */
265 } cubeb_device;
266 
267 /** Stream states signaled via state_callback. */
268 typedef enum {
269   CUBEB_STATE_STARTED, /**< Stream started. */
270   CUBEB_STATE_STOPPED, /**< Stream stopped. */
271   CUBEB_STATE_DRAINED, /**< Stream drained. */
272   CUBEB_STATE_ERROR    /**< Stream disabled due to error. */
273 } cubeb_state;
274 
275 /** Result code enumeration. */
276 enum {
277   CUBEB_OK = 0,                       /**< Success. */
278   CUBEB_ERROR = -1,                   /**< Unclassified error. */
279   CUBEB_ERROR_INVALID_FORMAT = -2,    /**< Unsupported #cubeb_stream_params requested. */
280   CUBEB_ERROR_INVALID_PARAMETER = -3, /**< Invalid parameter specified. */
281   CUBEB_ERROR_NOT_SUPPORTED = -4,     /**< Optional function not implemented in current backend. */
282   CUBEB_ERROR_DEVICE_UNAVAILABLE = -5 /**< Device specified by #cubeb_devid not available. */
283 };
284 
285 /**
286  * Whether a particular device is an input device (e.g. a microphone), or an
287  * output device (e.g. headphones). */
288 typedef enum {
289   CUBEB_DEVICE_TYPE_UNKNOWN,
290   CUBEB_DEVICE_TYPE_INPUT,
291   CUBEB_DEVICE_TYPE_OUTPUT
292 } cubeb_device_type;
293 
294 /**
295  * The state of a device.
296  */
297 typedef enum {
298   CUBEB_DEVICE_STATE_DISABLED, /**< The device has been disabled at the system level. */
299   CUBEB_DEVICE_STATE_UNPLUGGED, /**< The device is enabled, but nothing is plugged into it. */
300   CUBEB_DEVICE_STATE_ENABLED /**< The device is enabled. */
301 } cubeb_device_state;
302 
303 /**
304  * Architecture specific sample type.
305  */
306 typedef enum {
307   CUBEB_DEVICE_FMT_S16LE          = 0x0010, /**< 16-bit integers, Little Endian. */
308   CUBEB_DEVICE_FMT_S16BE          = 0x0020, /**< 16-bit integers, Big Endian. */
309   CUBEB_DEVICE_FMT_F32LE          = 0x1000, /**< 32-bit floating point, Little Endian. */
310   CUBEB_DEVICE_FMT_F32BE          = 0x2000  /**< 32-bit floating point, Big Endian. */
311 } cubeb_device_fmt;
312 
313 #if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__)
314 /** 16-bit integers, native endianess, when on a Big Endian environment. */
315 #define CUBEB_DEVICE_FMT_S16NE     CUBEB_DEVICE_FMT_S16BE
316 /** 32-bit floating points, native endianess, when on a Big Endian environment. */
317 #define CUBEB_DEVICE_FMT_F32NE     CUBEB_DEVICE_FMT_F32BE
318 #else
319 /** 16-bit integers, native endianess, when on a Little Endian environment. */
320 #define CUBEB_DEVICE_FMT_S16NE     CUBEB_DEVICE_FMT_S16LE
321 /** 32-bit floating points, native endianess, when on a Little Endian
322  *  environment. */
323 #define CUBEB_DEVICE_FMT_F32NE     CUBEB_DEVICE_FMT_F32LE
324 #endif
325 /** All the 16-bit integers types. */
326 #define CUBEB_DEVICE_FMT_S16_MASK  (CUBEB_DEVICE_FMT_S16LE | CUBEB_DEVICE_FMT_S16BE)
327 /** All the 32-bit floating points types. */
328 #define CUBEB_DEVICE_FMT_F32_MASK  (CUBEB_DEVICE_FMT_F32LE | CUBEB_DEVICE_FMT_F32BE)
329 /** All the device formats types. */
330 #define CUBEB_DEVICE_FMT_ALL       (CUBEB_DEVICE_FMT_S16_MASK | CUBEB_DEVICE_FMT_F32_MASK)
331 
332 /** Channel type for a `cubeb_stream`. Depending on the backend and platform
333  * used, this can control inter-stream interruption, ducking, and volume
334  * control.
335  */
336 typedef enum {
337   CUBEB_DEVICE_PREF_NONE          = 0x00,
338   CUBEB_DEVICE_PREF_MULTIMEDIA    = 0x01,
339   CUBEB_DEVICE_PREF_VOICE         = 0x02,
340   CUBEB_DEVICE_PREF_NOTIFICATION  = 0x04,
341   CUBEB_DEVICE_PREF_ALL           = 0x0F
342 } cubeb_device_pref;
343 
344 /** This structure holds the characteristics
345  *  of an input or output audio device. It is obtained using
346  *  `cubeb_enumerate_devices`, which returns these structures via
347  *  `cubeb_device_collection` and must be destroyed via
348  *  `cubeb_device_collection_destroy`. */
349 typedef struct {
350   cubeb_devid devid;          /**< Device identifier handle. */
351   char const * device_id;     /**< Device identifier which might be presented in a UI. */
352   char const * friendly_name; /**< Friendly device name which might be presented in a UI. */
353   char const * group_id;      /**< Two devices have the same group identifier if they belong to the same physical device; for example a headset and microphone. */
354   char const * vendor_name;   /**< Optional vendor name, may be NULL. */
355 
356   cubeb_device_type type;     /**< Type of device (Input/Output). */
357   cubeb_device_state state;   /**< State of device disabled/enabled/unplugged. */
358   cubeb_device_pref preferred;/**< Preferred device. */
359 
360   cubeb_device_fmt format;    /**< Sample format supported. */
361   cubeb_device_fmt default_format; /**< The default sample format for this device. */
362   uint32_t max_channels;      /**< Channels. */
363   uint32_t default_rate;      /**< Default/Preferred sample rate. */
364   uint32_t max_rate;          /**< Maximum sample rate supported. */
365   uint32_t min_rate;          /**< Minimum sample rate supported. */
366 
367   uint32_t latency_lo;        /**< Lowest possible latency in frames. */
368   uint32_t latency_hi;        /**< Higest possible latency in frames. */
369 } cubeb_device_info;
370 
371 /** Device collection.
372  *  Returned by `cubeb_enumerate_devices` and destroyed by
373  *  `cubeb_device_collection_destroy`. */
374 typedef struct {
375   cubeb_device_info * device; /**< Array of pointers to device info. */
376   size_t count;               /**< Device count in collection. */
377 } cubeb_device_collection;
378 
379 /** User supplied data callback.
380     - Calling other cubeb functions from this callback is unsafe.
381     - The code in the callback should be non-blocking.
382     - Returning less than the number of frames this callback asks for or
383       provides puts the stream in drain mode. This callback will not be called
384       again, and the state callback will be called with CUBEB_STATE_DRAINED when
385       all the frames have been output.
386     @param stream The stream for which this callback fired.
387     @param user_ptr The pointer passed to cubeb_stream_init.
388     @param input_buffer A pointer containing the input data, or nullptr
389                         if this is an output-only stream.
390     @param output_buffer A pointer to a buffer to be filled with audio samples,
391                          or nullptr if this is an input-only stream.
392     @param nframes The number of frames of the two buffer.
393     @retval If the stream has output, this is the number of frames written to
394             the output buffer. In this case, if this number is less than
395             nframes then the stream will start to drain. If the stream is
396             input only, then returning nframes indicates data has been read.
397             In this case, a value less than nframes will result in the stream
398             being stopped.
399     @retval CUBEB_ERROR on error, in which case the data callback will stop
400             and the stream will enter a shutdown state. */
401 typedef long (* cubeb_data_callback)(cubeb_stream * stream,
402                                      void * user_ptr,
403                                      void const * input_buffer,
404                                      void * output_buffer,
405                                      long nframes);
406 
407 /** User supplied state callback.
408     @param stream The stream for this this callback fired.
409     @param user_ptr The pointer passed to cubeb_stream_init.
410     @param state The new state of the stream. */
411 typedef void (* cubeb_state_callback)(cubeb_stream * stream,
412                                       void * user_ptr,
413                                       cubeb_state state);
414 
415 /**
416  * User supplied callback called when the underlying device changed.
417  * @param user The pointer passed to cubeb_stream_init. */
418 typedef void (* cubeb_device_changed_callback)(void * user_ptr);
419 
420 /**
421  * User supplied callback called when the underlying device collection changed.
422  * @param context A pointer to the cubeb context.
423  * @param user_ptr The pointer passed to cubeb_register_device_collection_changed. */
424 typedef void (* cubeb_device_collection_changed_callback)(cubeb * context,
425                                                           void * user_ptr);
426 
427 /** User supplied callback called when a message needs logging. */
428 typedef void (* cubeb_log_callback)(char const * fmt, ...);
429 
430 /** Initialize an application context.  This will perform any library or
431     application scoped initialization.
432 
433     Note: On Windows platforms, COM must be initialized in MTA mode on
434     any thread that will call the cubeb API.
435 
436     @param context A out param where an opaque pointer to the application
437                    context will be returned.
438     @param context_name A name for the context. Depending on the platform this
439                         can appear in different locations.
440     @param backend_name The name of the cubeb backend user desires to select.
441                         Accepted values self-documented in cubeb.c: init_oneshot
442                         If NULL, a default ordering is used for backend choice.
443                         A valid choice overrides all other possible backends,
444                         so long as the backend was included at compile time.
445     @retval CUBEB_OK in case of success.
446     @retval CUBEB_ERROR in case of error, for example because the host
447                         has no audio hardware. */
448 CUBEB_EXPORT int cubeb_init(cubeb ** context, char const * context_name,
449                                               char const * backend_name);
450 
451 /** Get a read-only string identifying this context's current backend.
452     @param context A pointer to the cubeb context.
453     @retval Read-only string identifying current backend. */
454 CUBEB_EXPORT char const * cubeb_get_backend_id(cubeb * context);
455 
456 /** Get the maximum possible number of channels.
457     @param context A pointer to the cubeb context.
458     @param max_channels The maximum number of channels.
459     @retval CUBEB_OK
460     @retval CUBEB_ERROR_INVALID_PARAMETER
461     @retval CUBEB_ERROR_NOT_SUPPORTED
462     @retval CUBEB_ERROR */
463 CUBEB_EXPORT int cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels);
464 
465 /** Get the minimal latency value, in frames, that is guaranteed to work
466     when creating a stream for the specified sample rate. This is platform,
467     hardware and backend dependent.
468     @param context A pointer to the cubeb context.
469     @param params On some backends, the minimum achievable latency depends on
470                   the characteristics of the stream.
471     @param latency_frames The latency value, in frames, to pass to
472                           cubeb_stream_init.
473     @retval CUBEB_OK
474     @retval CUBEB_ERROR_INVALID_PARAMETER
475     @retval CUBEB_ERROR_NOT_SUPPORTED */
476 CUBEB_EXPORT int cubeb_get_min_latency(cubeb * context,
477                                        cubeb_stream_params * params,
478                                        uint32_t * latency_frames);
479 
480 /** Get the preferred sample rate for this backend: this is hardware and
481     platform dependent, and can avoid resampling, and/or trigger fastpaths.
482     @param context A pointer to the cubeb context.
483     @param rate The samplerate (in Hz) the current configuration prefers.
484     @retval CUBEB_OK
485     @retval CUBEB_ERROR_INVALID_PARAMETER
486     @retval CUBEB_ERROR_NOT_SUPPORTED */
487 CUBEB_EXPORT int cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate);
488 
489 /** Destroy an application context. This must be called after all stream have
490  *  been destroyed.
491     @param context A pointer to the cubeb context.*/
492 CUBEB_EXPORT void cubeb_destroy(cubeb * context);
493 
494 /** Initialize a stream associated with the supplied application context.
495     @param context A pointer to the cubeb context.
496     @param stream An out parameter to be filled with the an opaque pointer to a
497                   cubeb stream.
498     @param stream_name A name for this stream.
499     @param input_device Device for the input side of the stream. If NULL the
500                         default input device is used. Passing a valid cubeb_devid
501                         means the stream only ever uses that device. Passing a NULL
502                         cubeb_devid allows the stream to follow that device type's
503                         OS default.
504     @param input_stream_params Parameters for the input side of the stream, or
505                                NULL if this stream is output only.
506     @param output_device Device for the output side of the stream. If NULL the
507                          default output device is used. Passing a valid cubeb_devid
508                          means the stream only ever uses that device. Passing a NULL
509                          cubeb_devid allows the stream to follow that device type's
510                          OS default.
511     @param output_stream_params Parameters for the output side of the stream, or
512                                 NULL if this stream is input only. When input
513                                 and output stream parameters are supplied, their
514                                 rate has to be the same.
515     @param latency_frames Stream latency in frames.  Valid range
516                           is [1, 96000].
517     @param data_callback Will be called to preroll data before playback is
518                          started by cubeb_stream_start.
519     @param state_callback A pointer to a state callback.
520     @param user_ptr A pointer that will be passed to the callbacks. This pointer
521                     must outlive the life time of the stream.
522     @retval CUBEB_OK
523     @retval CUBEB_ERROR
524     @retval CUBEB_ERROR_INVALID_FORMAT
525     @retval CUBEB_ERROR_DEVICE_UNAVAILABLE */
526 CUBEB_EXPORT int cubeb_stream_init(cubeb * context,
527                                    cubeb_stream ** stream,
528                                    char const * stream_name,
529                                    cubeb_devid input_device,
530                                    cubeb_stream_params * input_stream_params,
531                                    cubeb_devid output_device,
532                                    cubeb_stream_params * output_stream_params,
533                                    uint32_t latency_frames,
534                                    cubeb_data_callback data_callback,
535                                    cubeb_state_callback state_callback,
536                                    void * user_ptr);
537 
538 /** Destroy a stream. `cubeb_stream_stop` MUST be called before destroying a
539     stream.
540     @param stream The stream to destroy. */
541 CUBEB_EXPORT void cubeb_stream_destroy(cubeb_stream * stream);
542 
543 /** Start playback.
544     @param stream
545     @retval CUBEB_OK
546     @retval CUBEB_ERROR */
547 CUBEB_EXPORT int cubeb_stream_start(cubeb_stream * stream);
548 
549 /** Stop playback.
550     @param stream
551     @retval CUBEB_OK
552     @retval CUBEB_ERROR */
553 CUBEB_EXPORT int cubeb_stream_stop(cubeb_stream * stream);
554 
555 /** Get the current stream playback position.
556     @param stream
557     @param position Playback position in frames.
558     @retval CUBEB_OK
559     @retval CUBEB_ERROR */
560 CUBEB_EXPORT int cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position);
561 
562 /** Get the latency for this stream, in frames. This is the number of frames
563     between the time cubeb acquires the data in the callback and the listener
564     can hear the sound.
565     @param stream
566     @param latency Current approximate stream latency in frames.
567     @retval CUBEB_OK
568     @retval CUBEB_ERROR_NOT_SUPPORTED
569     @retval CUBEB_ERROR */
570 CUBEB_EXPORT int cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency);
571 
572 /** Get the input latency for this stream, in frames. This is the number of
573     frames between the time the audio input devices records the data, and they
574     are available in the data callback.
575     This returns CUBEB_ERROR when the stream is output-only.
576     @param stream
577     @param latency Current approximate stream latency in frames.
578     @retval CUBEB_OK
579     @retval CUBEB_ERROR_NOT_SUPPORTED
580     @retval CUBEB_ERROR */
581 CUBEB_EXPORT int cubeb_stream_get_input_latency(cubeb_stream * stream, uint32_t * latency);
582 /** Set the volume for a stream.
583     @param stream the stream for which to adjust the volume.
584     @param volume a float between 0.0 (muted) and 1.0 (maximum volume)
585     @retval CUBEB_OK
586     @retval CUBEB_ERROR_INVALID_PARAMETER volume is outside [0.0, 1.0] or
587             stream is an invalid pointer
588     @retval CUBEB_ERROR_NOT_SUPPORTED */
589 CUBEB_EXPORT int cubeb_stream_set_volume(cubeb_stream * stream, float volume);
590 
591 /** Change a stream's name.
592     @param stream the stream for which to set the name.
593     @param stream_name the new name for the stream
594     @retval CUBEB_OK
595     @retval CUBEB_ERROR_INVALID_PARAMETER if any pointer is invalid
596     @retval CUBEB_ERROR_NOT_SUPPORTED */
597 CUBEB_EXPORT int cubeb_stream_set_name(cubeb_stream * stream, char const * stream_name);
598 
599 /** Get the current output device for this stream.
600     @param stm the stream for which to query the current output device
601     @param device a pointer in which the current output device will be stored.
602     @retval CUBEB_OK in case of success
603     @retval CUBEB_ERROR_INVALID_PARAMETER if either stm, device or count are
604             invalid pointers
605     @retval CUBEB_ERROR_NOT_SUPPORTED */
606 CUBEB_EXPORT int cubeb_stream_get_current_device(cubeb_stream * stm,
607                                                  cubeb_device ** const device);
608 
609 /** Destroy a cubeb_device structure.
610     @param stream the stream passed in cubeb_stream_get_current_device
611     @param devices the devices to destroy
612     @retval CUBEB_OK in case of success
613     @retval CUBEB_ERROR_INVALID_PARAMETER if devices is an invalid pointer
614     @retval CUBEB_ERROR_NOT_SUPPORTED */
615 CUBEB_EXPORT int cubeb_stream_device_destroy(cubeb_stream * stream,
616                                              cubeb_device * devices);
617 
618 /** Set a callback to be notified when the output device changes.
619     @param stream the stream for which to set the callback.
620     @param device_changed_callback a function called whenever the device has
621            changed. Passing NULL allow to unregister a function
622     @retval CUBEB_OK
623     @retval CUBEB_ERROR_INVALID_PARAMETER if either stream or
624             device_changed_callback are invalid pointers.
625     @retval CUBEB_ERROR_NOT_SUPPORTED */
626 CUBEB_EXPORT int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
627                                                                cubeb_device_changed_callback device_changed_callback);
628 
629 /** Return the user data pointer registered with the stream with cubeb_stream_init.
630     @param stream the stream for which to retrieve user data pointer.
631     @retval user data pointer */
632 CUBEB_EXPORT void * cubeb_stream_user_ptr(cubeb_stream * stream);
633 
634 /** Returns enumerated devices.
635     @param context
636     @param devtype device type to include
637     @param collection output collection. Must be destroyed with cubeb_device_collection_destroy
638     @retval CUBEB_OK in case of success
639     @retval CUBEB_ERROR_INVALID_PARAMETER if collection is an invalid pointer
640     @retval CUBEB_ERROR_NOT_SUPPORTED */
641 CUBEB_EXPORT int cubeb_enumerate_devices(cubeb * context,
642                                          cubeb_device_type devtype,
643                                          cubeb_device_collection * collection);
644 
645 /** Destroy a cubeb_device_collection, and its `cubeb_device_info`.
646     @param context
647     @param collection collection to destroy
648     @retval CUBEB_OK
649     @retval CUBEB_ERROR_INVALID_PARAMETER if collection is an invalid pointer */
650 CUBEB_EXPORT int cubeb_device_collection_destroy(cubeb * context,
651                                                  cubeb_device_collection * collection);
652 
653 /** Registers a callback which is called when the system detects
654     a new device or a device is removed.
655     @param context
656     @param devtype device type to include. Different callbacks and user pointers
657            can be registered for each devtype. The hybrid devtype
658            `CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT` is also valid
659            and will register the provided callback and user pointer in both sides.
660     @param callback a function called whenever the system device list changes.
661            Passing NULL allow to unregister a function. You have to unregister
662            first before you register a new callback.
663     @param user_ptr pointer to user specified data which will be present in
664            subsequent callbacks.
665     @retval CUBEB_ERROR_NOT_SUPPORTED */
666 CUBEB_EXPORT int cubeb_register_device_collection_changed(cubeb * context,
667                                                           cubeb_device_type devtype,
668                                                           cubeb_device_collection_changed_callback callback,
669                                                           void * user_ptr);
670 
671 /** Set a callback to be called with a message.
672     @param log_level CUBEB_LOG_VERBOSE, CUBEB_LOG_NORMAL.
673     @param log_callback A function called with a message when there is
674                         something to log. Pass NULL to unregister.
675     @retval CUBEB_OK in case of success.
676     @retval CUBEB_ERROR_INVALID_PARAMETER if either context or log_callback are
677                                           invalid pointers, or if level is not
678                                           in cubeb_log_level. */
679 CUBEB_EXPORT int cubeb_set_log_callback(cubeb_log_level log_level,
680                                         cubeb_log_callback log_callback);
681 
682 #if defined(__cplusplus)
683 }
684 #endif
685 
686 #endif /* CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382 */
687