From 7706a101a6f7928cf7e3fc63b979352b3af214b3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 9 Jun 2008 17:27:43 +0000 Subject: add complete documentation git-svn-id: file:///home/lennart/svn/public/libcanberra/trunk@57 01b60673-d06a-42c0-afdd-89cb8e0f78ac --- src/common.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 290 insertions(+), 3 deletions(-) (limited to 'src/common.c') diff --git a/src/common.c b/src/common.c index 80be86c..a7b6945 100644 --- a/src/common.c +++ b/src/common.c @@ -33,6 +33,97 @@ #include "proplist.h" #include "macro.h" +/** + * SECTION:canberra + * @short_description: General libcanberra API + * + * libcanberra defines a simple abstract interface for playing event sounds. + * + * libcanberra relies on the XDG sound naming specification for + * identifying event sounds. On Unix/Linux the right sound to play is + * found via the mechanisms defined in the XDG sound themeing + * specification. On other systems the XDG sound name is translated to + * the native sound id for the operating system. + * + * An event sound is triggered via libcanberra by calling the + * ca_context_play() function on a previously created ca_context + * object. The ca_context_play() takes a list of key-value pairs that + * describe the event sound to generate as closely as possible. The + * most important property is %CA_PROP_EVENT_ID which defines the XDG + * sound name for the sound to play. + * + * libcanberra is not a generic event abstraction system. It's only + * purpose is playing sounds -- however in a very elaborate way. As + * much information about the context the sound is triggered from + * shall be supplied to the sound system as possible, so that it can + * replace the sound with some other kind of feedback for a11y + * cases. Also this additional information can be used to enhance user + * experience (e.g. by positioning sounds in space depending on the + * place on the screen the sound was triggered from, and similar + * uses). + * + * The set of properties defined for event sounds is extensible and + * shared with other audio systems, such as PulseAudio. Some of + * the properties that may be set are specific to an application, to a + * window, to an input event or to the media being played back. + * + * The user can attach a set of properties to the context itself, + * which is than automatically inherited by each sample being played + * back. (ca_context_change_props()). + * + * Some of the properties can be filled in by libcanberra or one of + * its backends automatically and thus need not be be filled in by the + * application (such as %CA_PROP_APPLICATION_PROCESS_ID and + * friends). However the application can always overwrite any of these + * implicit properties. + * + * libcanberra is thread-safe and OOM-safe (as far as the backend + * allows this). It is not async-signal safe. + * + * Most libcanberra functions return an integer that indicates success + * when 0 (%CA_SUCCESS) or an error when negative. In the latter case + * ca_strerror() can be used to convert this code into a human + * readable string. + * + * libcanberra property names need to be in 7bit ASCII, string + * property values UTF8. + * + * Optionally a libcanberra backend can support caching of sounds in a + * sound system. If this functionality is used, the latencies for + * event sound playback can be much smaller and fewer resources are + * needed to start playback. If a backend does not support cacheing, + * the respective functions will return an error code of + * %CA_ERROR_NOTSUPPORTED. + * + * It is highly recommended that the application sets the + * %CA_PROP_APPLICATION_NAME, %CA_PROP_APPLICATION_ID, + * %CA_PROP_APPLICATION_ICON_NAME/%CA_PROP_APPLICATION_ICON properties + * immediately after creating the ca_context, before calling + * ca_context_open() or ca_context_play(). + * + * Its is highly recommended to pass at least %CA_PROP_EVENT_ID, + * %CA_PROP_EVENT_DESCRIPTION to ca_context_play() for each event + * sound generated. For sound events based on mouse inputs events + * %CA_PROP_EVENT_MOUSE_X, %CA_PROP_EVENT_MOUSE_Y, %CA_PROP_EVENT_MOUSE_HPOS, + * %CA_PROP_EVENT_MOUSE_VPOS, %CA_PROP_EVENT_MOUSE_BUTTON should be + * passed. For sound events attached to a widget on the screen, the + * %CA_PROP_WINDOW_xxx properties should be set. + * + * + */ + +/** + * ca_context_create: + * @c: A pointer wheere to fill in the newly created context object. + * + * Create an (unconnected) context object. This call will not connect + * to the sound system, calling this function might even suceed if no + * working driver backend is available. To find out if one is + * available call ca_context_open(). + * + * Returns: 0 on success, negative error code on error. + */ + int ca_context_create(ca_context **_c) { ca_context *c; int ret; @@ -71,6 +162,14 @@ int ca_context_create(ca_context **_c) { return CA_SUCCESS; } +/** + * ca_context_destroy: + * @c: the context to destroy. + * + * Destroy a (connected or unconnected) context object. + * + * Returns: 0 on success, negative error code on error. + */ int ca_context_destroy(ca_context *c) { int ret = CA_SUCCESS; @@ -96,6 +195,18 @@ int ca_context_destroy(ca_context *c) { return ret; } +/** + * ca_context_set_driver: + * @c: the context to change the backend driver for + * @driver: the backend driver to use (e.g. "alsa", "pulse", "null", ...) + * + * Specify the backend driver used. This function may not be called again after + * ca_context_open() suceeded. This function might suceed even when + * the specified driver backend is not available. Use + * ca_context_open() to find out whether the backend is available. + * + * Returns: 0 on success, negative error code on error. + */ int ca_context_set_driver(ca_context *c, const char *driver) { char *n; int ret; @@ -104,7 +215,9 @@ int ca_context_set_driver(ca_context *c, const char *driver) { ca_mutex_lock(c->mutex); ca_return_val_if_fail_unlock(!c->opened, CA_ERROR_STATE, c->mutex); - if (!(n = ca_strdup(driver))) { + if (!driver) + n = NULL; + else if (!(n = ca_strdup(driver))) { ret = CA_ERROR_OOM; goto fail; } @@ -120,6 +233,21 @@ fail: return ret; } +/** + * ca_context_change_device: + * @c: the context to change the backend device for + * @device: the backend device to use, in a format that is specific to the backend. + * + * Specify the backend device to use. This function may be called not be called after + * ca_context_open() suceeded. This function might suceed even when + * the specified driver backend is not available. Use + * ca_context_open() to find out whether the backend is available + * + * Depending on the backend use this might or might not cause all + * currently playing event sounds to be moved to the new device.. + * + * Returns: 0 on success, negative error code on error. + */ int ca_context_change_device(ca_context *c, const char *device) { char *n; int ret; @@ -127,7 +255,9 @@ int ca_context_change_device(ca_context *c, const char *device) { ca_return_val_if_fail(c, CA_ERROR_INVALID); ca_mutex_lock(c->mutex); - if (!(n = ca_strdup(device))) { + if (!device) + n = NULL; + else if (!(n = ca_strdup(device))) { ret = CA_ERROR_OOM; goto fail; } @@ -160,6 +290,17 @@ static int context_open_unlocked(ca_context *c) { return ret; } +/** + * ca_context_open: + * @c: the context to connect. + * + * Connect the context to the sound system. This call is implicitly + * called in ca_context_play() or ca_context_cache() if not called + * explicitly. It is recommended to initialize application properties + * with ca_context_change_props() before calling this function. + * + * Returns: 0 on success, negative error code on error. + */ int ca_context_open(ca_context *c) { int ret; @@ -217,6 +358,24 @@ fail: return ret; } +/** + * ca_context_change_props: + * @c: the context to set the properties on. + * @...: the list of string pairs for the properties. Needs to be a NULL terminated list. + * + * Write one or more string properties to the context object. Requires + * final NULL sentinel. Properties set like this will be attached to + * both the client object of the sound server and to all event sounds + * played or cached. It is recommended to call this function at least + * once before calling ca_context_open(), so that the initial + * application properties are set properly before the initial + * connection to the sound system. This function can be called both + * before and after the ca_context_open() call. Properties that have + * already been set before will be overwritten. + * + * Returns: 0 on success, negative error code on error. + */ + int ca_context_change_props(ca_context *c, ...) { va_list ap; int ret; @@ -238,6 +397,18 @@ int ca_context_change_props(ca_context *c, ...) { return ret; } +/** + * ca_context_change_props_full: + * @c: the context to set the properties on. + * @p: the property list to set. + * + * Similar to ca_context_change_props(), but takes a ca_proplist + * instead of a variable list of properties. Can be used to set binary + * properties such as %CA_PROP_APPLICATION_ICON. + * + * Returns: 0 on success, negative error code on error. + */ + int ca_context_change_props_full(ca_context *c, ca_proplist *p) { int ret; ca_proplist *merged; @@ -265,6 +436,48 @@ finish: return ret; } +/** + * ca_context_play: + * @c: the context to play the event sound on + * @id: an integer id this sound can later be identified with when calling ca_context_cancel() + * @...: additional properties for this sound event. + * + * Play one event sound. id can be any numeric value which later can + * be used to cancel an event sound that is currently being + * played. You may use the same id twice or more times if you want to + * cancel multiple event sounds with a single ca_context_cancel() call + * at once. It is recommended to pass 0 for the id if the event sound + * shall never be canceled. If the requested sound is not cached in + * the server yet this call might result in the sample being uploaded + * temporarily or permanently (this may be controlled with %CA_PROP_CANBERRA_CACHE_CONTROL). This function will start playback + * in the background. It will not wait until playback + * completed. Depending on the backend used a sound that is started + * shortly before your application terminates might or might not continue to + * play after your application terminated. If you want to make sure + * that all sounds finish to play you need to wait synchronously for + * the callback function of ca_context_play_full() to be called before you + * terminate your application. + * + * The sample to play is identified by the %CA_PROP_EVENT_ID + * property. If it is already cached in the server the cached version + * is played. The properties passed in this call are merged with the + * properties supplied when the sample was cached (if applicable) + * and the context properties as set with ca_context_change_props(). + * + * If %CA_PROP_EVENT_ID is not defined the sound file passed in the + * %CA_PROP_MEDIA_FILENAME is played. + * + * On Linux/Unix the right sound to play is determined according to + * %CA_PROP_EVENT_ID, + * %CA_PROP_APPLICATION_LANGUAGE/%CA_PROP_MEDIA_LANGUAGE, the system + * locale, %CA_PROP_CANBERRA_XDG_THEME_NAME and + * %CA_PROP_CANBERRA_XDG_THEME_OUTPUT_PROFILE, following the XDG Sound + * Theming Specification. On non-Unix systems the native event sound + * that matches the XDG sound name in %CA_PROP_EVENT_ID is played. + * + * Returns: 0 on success, negative error code on error. + */ + int ca_context_play(ca_context *c, uint32_t id, ...) { int ret; va_list ap; @@ -286,6 +499,25 @@ int ca_context_play(ca_context *c, uint32_t id, ...) { return ret; } +/** + * ca_context_play_full: + * @c: the context to play the event sound on + * @id: an integer id this sound can be later be identified with when calling ca_context_cancel() or when the callback is called. + * @p: A property list of properties for this event sound + * @cb: A callback to call when this sound event sucessfully finished playing or when an error occured during playback. + * + * Play one event sound, and call the specified callback function when + * completed. See ca_finish_callback_t for the semantics the callback + * is called in. Also see ca_context_play(). + * + * It is guaranteed that the callback is called exactly once if + * ca_context_play_full() returns CA_SUCCESS. You thus may safely pass + * allocated memory to the callback and assume that it is freed + * properly. + * + * Returns: 0 on success, negative error code on error. + */ + int ca_context_play_full(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t cb, void *userdata) { int ret; @@ -303,6 +535,8 @@ int ca_context_play_full(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_c ca_assert(c->opened); + fprintf(stderr, "Playing %s\n", ca_proplist_gets_unlocked(p, CA_PROP_EVENT_ID)); + ret = driver_play(c, id, p, cb, userdata); finish: @@ -312,6 +546,20 @@ finish: return ret; } +/** + * + * ca_context_cancel: + * @c: the context to cancel the sounds on + * @id: the id that identify the sounds to cancel. + * + * Cancel one or more event sounds that have been started via + * ca_context_play(). If the sound was started with + * ca_context_play_full() and a callback function was passed this + * might cause this function to be called with %CA_ERROR_CANCELED as + * error code. + * + * Returns: 0 on success, negative error code on error. + */ int ca_context_cancel(ca_context *c, uint32_t id) { int ret; @@ -326,6 +574,24 @@ int ca_context_cancel(ca_context *c, uint32_t id) { return ret; } +/** + * ca_context_cache: + * @c: The context to use for uploading. + * @...: The properties for this event sound. Terminated with NULL. + * + * Upload the specified sample into the audio server and attach the + * specified properties to it. This function will only return after + * the sample upload was finished. + * + * The sound to cache is found with the same algorithm that is used to + * find the sounds for ca_context_play(). + * + * If the backend doesn't support caching sound samples this function + * will return %CA_ERROR_NOTSUPPORTED. + * + * Returns: 0 on success, negative error code on error. + */ + int ca_context_cache(ca_context *c, ...) { int ret; va_list ap; @@ -347,6 +613,20 @@ int ca_context_cache(ca_context *c, ...) { return ret; } +/** + * ca_context_cache_full: + * @c: The context to use for uploading. + * @p: The property list for this event sound. + * + * Upload the specified sample into the server and attach the + * specified properties to it. Similar to ca_context_cache() but takes + * a ca_proplist instead of a variable number of arguments. + * + * If the backend doesn't support caching sound samples this function + * will return CA_ERROR_NOTSUPPORTED. + * + * Returns: 0 on success, negative error code on error. + */ int ca_context_cache_full(ca_context *c, ca_proplist *p) { int ret; @@ -372,7 +652,14 @@ finish: return ret; } -/** Return a human readable error */ +/** + * ca_strerror: + * @code: Numerical error code as returned by a canberra API function + * + * Converts a numerical error code as returned by most canberra API functions into a human readable error string. + * + * Returns: a human readable error string. + */ const char *ca_strerror(int code) { const char * const error_table[-_CA_ERROR_MAX] = { -- cgit