From 181e9c6d5d11cb1e5d36a2777eeb233ad8ed00e5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Oct 2008 18:15:23 +0200 Subject: big pile of updates to match more what happened with libcanberra --- src/sydney.h | 541 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 403 insertions(+), 138 deletions(-) (limited to 'src/sydney.h') diff --git a/src/sydney.h b/src/sydney.h index 58324ca..cdc006c 100644 --- a/src/sydney.h +++ b/src/sydney.h @@ -1,33 +1,39 @@ #ifndef foosydneyhfoo #define foosydneyhfoo -#ifdef __cplusplus -extern "C" { -#endif +/*** + This file is part of libsydney. + + Copyright 2007-2008 Lennart Poettering + + libsydney is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 2.1 of the + License, or (at your option) any later version. + + libsydney is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. -/* - Requirements & General observations - - - In sync mode, the device will automatically write data so that an - initial read causes writes of zeros to be issued to that one can - do "while (1); {read(); write()} - - All functions are thread-safe and can be called in any thread - context. None of the functions is async-signal safe. - - It is assumed that duplex streams have a single clock (synchronised) - - Property set extensible. To be kept in sync with PulseAudio and libsydney. - - Property keys need to be valid UTF-8, text values, too. - - Will warn if application.name or application.id not set. - - Error codes are returned immediately, as negative integers - - application.process.* will be filled in automatically but may be overwritten by the client. - They thus should not be used for authentication purposes. - - It is recommended to set most properties before the _open() call. - -*/ + You should have received a copy of the GNU Lesser General Public + License along with libsydney. If not, see + . +***/ #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __GNUC__ +/* Make sure __attribute__ works on non-gcc systems. Yes, might be a bit ugly */ +#define __attribute__(x) +#endif + /* Detect byte order, based on sys/param.h */ #if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || defined(WIN32) #define SA_LITTLE_ENDIAN 1 @@ -39,8 +45,269 @@ extern "C" { #error "Cannot determine byte order!" #endif +/** + * SA_PROP_MEDIA_NAME: + * + * A name describing the media being played. Localized if possible and applicable. + */ +#define SA_PROP_MEDIA_NAME "media.name" + +/** + * SA_PROP_MEDIA_TITLE: + * + * A (song) title describing the media being played. Localized if possible and applicable. + */ +#define SA_PROP_MEDIA_TITLE "media.title" + +/** + * SA_PROP_MEDIA_ARTIST: + * + * The artist of this media. Localized if possible and applicable. + */ +#define SA_PROP_MEDIA_ARTIST "media.artist" + +/** + * SA_PROP_MEDIA_LANGUAGE: + * + * The language this media is in, in some standard POSIX locale string, such as "de_DE". + */ +#define SA_PROP_MEDIA_LANGUAGE "media.language" + +/** + * SA_PROP_MEDIA_FILENAME: + * + * The file name this media was or can be loaded from. + */ +#define SA_PROP_MEDIA_FILENAME "media.filename" + +/** + * SA_PROP_MEDIA_ICON: + * + * An icon for this media in binary PNG format. + */ +#define SA_PROP_MEDIA_ICON "media.icon" + +/** + * SA_PROP_MEDIA_ICON_NAME: + * + * An icon name as defined in the XDG icon naming specifcation. + */ +#define SA_PROP_MEDIA_ICON_NAME "media.icon_name" + +/** + * SA_PROP_MEDIA_ROLE: + * + * The "role" this media is played in. For event sounds the string + * "event". For other cases strings like "music", "video", "game", ... + */ +#define SA_PROP_MEDIA_ROLE "media.role" + +/** + * SA_PROP_EVENT_ID: + * + * A textual id for an event sound, as mandated by the XDG sound naming specification. + */ +#define SA_PROP_EVENT_ID "event.id" + +/** + * SA_PROP_EVENT_DESCRIPTION: + * + * A descriptive string for the sound event. Localized if possible and applicable. + */ +#define SA_PROP_EVENT_DESCRIPTION "event.description" + +/** + * SA_PROP_EVENT_MOUSE_X: + * + * If this sound event was triggered by a mouse input event, the X + * position of the mouse cursor on the screen, formatted as string. + */ +#define SA_PROP_EVENT_MOUSE_X "event.mouse.x" + +/** + * SA_PROP_EVENT_MOUSE_Y: + * + * If this sound event was triggered by a mouse input event, the Y + * position of the mouse cursor on the screen, formatted as string. + */ +#define SA_PROP_EVENT_MOUSE_Y "event.mouse.y" + +/** + * SA_PROP_EVENT_MOUSE_HPOS: + * + * If this sound event was triggered by a mouse input event, the X + * position of the mouse cursor as fractional value between 0 and 1, + * formatted as string, 0 reflecting the left side of the screen, 1 + * the right side. + */ +#define SA_PROP_EVENT_MOUSE_HPOS "event.mouse.hpos" + +/** + * SA_PROP_EVENT_MOUSE_VPOS: + * + * If this sound event was triggered by a mouse input event, the Y + * position of the mouse cursor as fractional value between 0 and 1, + * formatted as string, 0 reflecting the top end of the screen, 1 + * the bottom end. + */ +#define SA_PROP_EVENT_MOUSE_VPOS "event.mouse.vpos" + +/** + * SA_PROP_EVENT_MOUSE_BUTTON: + * + * If this sound event was triggered by a mouse input event, the + * number of the mouse button that triggered it, formatted as string. 1 + * for left mouse button, 3 for right, 2 for middle. + */ +#define SA_PROP_EVENT_MOUSE_BUTTON "event.mouse.button" + +/** + * SA_PROP_WINDOW_NAME: + * + * If this sound event was triggered by a window on the screen, the + * name of this window as human readable string. + */ +#define SA_PROP_WINDOW_NAME "window.name" + +/** + * SA_PROP_WINDOW_ID: + * + * If this sound event was triggered by a window on the screen, some + * identification string for this window, so that the sound system can + * recognize specific windows. + */ +#define SA_PROP_WINDOW_ID "window.id" + +/** + * SA_PROP_WINDOW_ICON: + * + * If this sound event was triggered by a window on the screen, binary + * icon data in PNG format for this window. + */ +#define SA_PROP_WINDOW_ICON "window.icon" + +/** + * SA_PROP_WINDOW_ICON_NAME: + * + * If this sound event was triggered by a window on the screen, an + * icon name for this window, as defined in the XDG icon naming + * specification. + */ +#define SA_PROP_WINDOW_ICON_NAME "window.icon_name" + +/** + * SA_PROP_WINDOW_X11_DISPLAY: + * + * If this sound event was triggered by a window on the screen and the + * windowing system is X11, the X display name of the window (e.g. ":0"). + */ +#define SA_PROP_WINDOW_X11_DISPLAY "window.x11.display" + +/** + * SA_PROP_WINDOW_X11_SCREEN: + * + * If this sound event was triggered by a window on the screen and the + * windowing system is X11, the X screen id of the window formatted as + * string (e.g. "0"). + */ +#define SA_PROP_WINDOW_X11_SCREEN "window.x11.screen" + +/** + * SA_PROP_WINDOW_X11_MONITOR: + * + * If this sound event was triggered by a window on the screen and the + * windowing system is X11, the X monitor id of the window formatted as + * string (e.g. "0"). + */ +#define SA_PROP_WINDOW_X11_MONITOR "window.x11.monitor" + +/** + * SA_PROP_WINDOW_X11_XID: + * + * If this sound event was triggered by a window on the screen and the + * windowing system is X11, the XID of the window formatted as string. + */ +#define SA_PROP_WINDOW_X11_XID "window.x11.xid" + +/** + * SA_PROP_APPLICATION_NAME: + * + * The name of the application this sound event was triggered by as + * human readable string. (e.g. "GNU Emacs") Localized if possible and + * applicable. + */ +#define SA_PROP_APPLICATION_NAME "application.name" + +/** + * SA_PROP_APPLICATION_ID: + * + * An identifier for the program this sound event was triggered + * by. (e.g. "org.gnu.emacs"). + */ +#define SA_PROP_APPLICATION_ID "application.id" + +/** + * SA_PROP_APPLICATION_VERSION: + * + * A version number for the program this sound event was triggered + * by. (e.g. "22.2") + */ +#define SA_PROP_APPLICATION_VERSION "application.version" + +/** + * SA_PROP_APPLICATION_ICON: + * + * Binary icon data in PNG format for the application this sound event + * is triggered by. + */ +#define SA_PROP_APPLICATION_ICON "application.icon" + +/** + * SA_PROP_APPLICATION_ICON_NAME: + * + * An icon name for the application this sound event is triggered by, + * as defined in the XDG icon naming specification. + */ +#define SA_PROP_APPLICATION_ICON_NAME "application.icon_name" + +/** + * SA_PROP_APPLICATION_LANGUAGE: + * + * The locale string the application that is triggering this sound + * event is running in. A POSIX locale string such as de_DE@euro. + */ +#define SA_PROP_APPLICATION_LANGUAGE "application.language" + +/** + * SA_PROP_APPLICATION_PROCESS_ID: + * + * The unix PID of the process that is triggering this sound event, formatted as string. + */ +#define SA_PROP_APPLICATION_PROCESS_ID "application.process.id" + +/** + * SA_PROP_APPLICATION_PROCESS_BINARY: + * + * The path to the process binary of the process that is triggering this sound event. + */ +#define SA_PROP_APPLICATION_PROCESS_BINARY "application.process.binary" + +/** + * SA_PROP_APPLICATION_PROCESS_USER: + * + * The user that owns the process that is triggering this sound event. + */ +#define SA_PROP_APPLICATION_PROCESS_USER "application.process.user" + +/** + * SA_PROP_APPLICATION_PROCESS_HOST: + * + * The host name of the host the process that is triggering this sound event runs on. + */ +#define SA_PROP_APPLICATION_PROCESS_HOST "application.process.host" + /** Stream object */ -typedef struct sa_stream sa_stream_t; +typedef struct sa_stream sa_stream; /** Volume that corresponds to muted in/out */ #define SA_VOLUME_MUTED ((int32_t) (-0x80000000)) @@ -104,23 +371,34 @@ typedef enum { _SA_MODE_MAX = 4 } sa_mode_t; -/** Error codes */ +/** + * Error codes: + * SCA_SUCCESS: Success + * + * Error codes + */ enum { SA_SUCCESS = 0, - SA_ERROR_NOT_SUPPORTED = -1, + SA_ERROR_NOTSUPPORTED = -1, SA_ERROR_INVALID = -2, SA_ERROR_STATE = -3, SA_ERROR_OOM = -4, - SA_ERROR_NO_DEVICE = -5, - SA_ERROR_NO_DRIVER = -6, - SA_ERROR_NO_CODEC = -7, - SA_ERROR_NO_PCM_FORMAT = -7, - SA_ERROR_SYSTEM = -8, - SA_ERROR_NO_INIT = -9, - SA_ERROR_NO_META = -10, - SA_ERROR_NO_DATA = -11, - SA_ERROR_NO_SPACE = -12, - _SA_ERROR_MAX = -13 + SA_ERROR_NODRIVER = -5, + SA_ERROR_SYSTEM = -6, + SA_ERROR_CORRUPT = -7, + SA_ERROR_TOOBIG = -8, + SA_ERROR_NOTFOUND = -9, + SA_ERROR_DESTROYED = -10, + SA_ERROR_CANCELED = -11, + SA_ERROR_NOTAVAILABLE = -12, + SA_ERROR_ACCESS = -13, + SA_ERROR_IO = -14, + SA_ERROR_INTERNAL = -15, + SA_ERROR_DISABLED = -16, + SA_ERROR_NODEVICE = -17, + SA_ERROR_NOCODEC = -18, + SA_ERROR_NOPCMFORMAT = -19, + _SA_ERROR_MAX = -20 }; /** Possible events for notifications */ @@ -219,6 +497,7 @@ typedef enum { SA_STATE_RUNNING, SA_STATE_STOPPED, SA_STATE_DRAINING, + SA_STATE_DEAD, /* put more stuff */ _SA_STATE_MAX } sa_state_t; @@ -236,185 +515,171 @@ typedef enum { SA_ADJUST_NONE = 0 } sa_adjust_t; -/** Stream properties */ -#define SA_PROP_MEDIA_NAME "media.name" -#define SA_PROP_MEDIA_TITLE "media.title" -#define SA_PROP_MEDIA_ARTIST "media.artist" -#define SA_PROP_MEDIA_LANGUAGE "media.language" -#define SA_PROP_MEDIA_FILENAME "media.filename" -#define SA_PROP_MEDIA_ICON "media.icon" -#define SA_PROP_MEDIA_ICON_NAME "media.icon_name" -#define SA_PROP_MEDIA_ROLE "media.role" -#define SA_PROP_EVENT_ID "event.id" -#define SA_PROP_EVENT_X11_DISPLAY "event.x11.display" -#define SA_PROP_EVENT_X11_XID "event.x11.xid" -#define SA_PROP_EVENT_MOUSE_X "event.mouse.x" -#define SA_PROP_EVENT_MOUSE_Y "event.mouse.y" -#define SA_PROP_EVENT_MOUSE_BUTTON "event.mouse.button" -#define SA_PROP_APPLICATION_NAME "application.name" -#define SA_PROP_APPLICATION_ID "application.id" -#define SA_PROP_APPLICATION_VERSION "application.version" -#define SA_PROP_APPLICATION_ICON "application.icon" -#define SA_PROP_APPLICATION_ICON_NAME "application.icon_name" -#define SA_PROP_APPLICATION_LANGUAGE "application.language" -#define SA_PROP_APPLICATION_PROCESS_ID "application.process.id" -#define SA_PROP_APPLICATION_PROCESS_BINARY "application.process.binary" -#define SA_PROP_APPLICATION_PROCESS_USER "application.process.user" -#define SA_PROP_APPLICATION_PROCESS_HOST "application.process.host" - /** Main callback function */ -typedef int (*sa_event_callback_t)(sa_stream_t *s, sa_event_t event); +typedef int (*sa_event_callback_t)(sa_stream *s, sa_event_t event); + +/** + * sa_proplist: + * + * A sydney property list object. Basically a hashtable. + */ +typedef struct sa_proplist sa_proplist; + +int sa_proplist_create(sa_proplist **p); +int sa_proplist_destroy(sa_proplist *p); +int sa_proplist_sets(sa_proplist *p, const char *key, const char *value); +int sa_proplist_setf(sa_proplist *p, const char *key, const char *format, ...) __attribute__((format(printf, 3, 4))); +int sa_proplist_set(sa_proplist *p, const char *key, const void *data, size_t nbytes); /** Create an opaque (e.g. AC3) codec stream */ -int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec); +int sa_stream_create_opaque(sa_stream **s, sa_mode_t mode, const char *codec); /** Normal way to open a PCM device */ -int sa_stream_create_pcm(sa_stream_t **s, const char *client_name, sa_mode_t mode, sa_pcm_format_t format, unsigned rate, unsigned nchannels); +int sa_stream_create_pcm(sa_stream **s, sa_mode_t mode, sa_pcm_format_t format, unsigned rate, unsigned nchannels); /** Initialise the device */ -int sa_stream_open(sa_stream_t *s); +int sa_stream_open(sa_stream *s); /** Close/destroy everything */ -int sa_stream_destroy(sa_stream_t *s); +int sa_stream_destroy(sa_stream *s); /* Buffer params */ -int sa_stream_set_write_latency(sa_stream_t *s, size_t nbytes); -int sa_stream_set_write_wakeup(sa_stream_t *s, size_t nbytes); -int sa_stream_set_read_latency(sa_stream_t *s, size_t nbytes); -int sa_stream_set_read_wakeup(sa_stream_t *s, size_t nbytes); +int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes); +int sa_stream_change_read_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes); /** Set the mapping between channels and the loudspeakers */ -int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned n); +int sa_stream_set_channel_map(sa_stream *s, const sa_channel_t map[], unsigned n); /** Whether xruns cause the card to reset */ -int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode); +int sa_stream_set_xrun_mode(sa_stream *s, sa_xrun_mode_t mode); /** Set the device to non-interleaved mode */ -int sa_stream_set_non_interleaved(sa_stream_t *s, int enable); +int sa_stream_set_non_interleaved(sa_stream *s, int enable); /** Allow that the sample rate may be changed during runtime */ -int sa_stream_set_dynamic_rate(sa_stream_t *s, int enabled); - -/** Set the number of PCM channels for input */ -int sa_stream_set_read_pcm_nchannels(sa_stream *s, unsigned nchannels); - -/** Set the number of PCM channels for output */ -int sa_stream_set_write_pcm_nchannels(sa_stream *s, unsigned nchannels); +int sa_stream_set_dynamic_pcm_rate(sa_stream *s, int enabled); /** Select driver */ -int sa_stream_set_driver(sa_stream_t *s, const char *driver); - -/** Start callback thread */ -int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback); +int sa_stream_set_driver(sa_stream *s, const char *driver); -/** Start callback thread */ -int sa_stream_stop_thread(sa_stream_t *s); +/** Enable asynchronous mode and set event callback*/ +int sa_stream_set_event_callback(sa_stream *s, sa_event_callback_t callback); /** Change the device connected to the stream */ -int sa_stream_change_device(sa_stream_t *s, const char *device_name); +int sa_stream_change_device(sa_stream *s, const char *device_name); /** volume in hundreths of dB*/ -int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned n); +int sa_stream_change_read_volume(sa_stream *s, const int32_t vol[], unsigned n); /** volume in hundreths of dB*/ -int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned n); +int sa_stream_change_write_volume(sa_stream *s, const int32_t vol[], unsigned n); /** Change the sampling rate */ -int sa_stream_change_rate(sa_stream_t *s, unsigned rate); +int sa_stream_change_pcm_rate(sa_stream *s, unsigned rate); + +int sa_stream_change_props(sa_stream *c, ...) __attribute__((sentinel)); +int sa_stream_change_props_full(sa_stream *c, sa_proplist *p); /** Associate opaque user data */ -int sa_stream_change_user_data(sa_stream_t *s, const void *value); +int sa_stream_change_user_data(sa_stream *s, const void *value); /* Hardware-related. This is implementation-specific and hardware specific. */ -int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction); -int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction); -int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction); +int sa_stream_set_adjust_rate(sa_stream *s, sa_adjust_t direction); +int sa_stream_set_adjust_nchannels(sa_stream *s, sa_adjust_t direction); +int sa_stream_set_adjust_pcm_format(sa_stream *s, sa_adjust_t direction); /* Query functions */ -int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode); -int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size); -int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format); -int sa_stream_get_pcm_rate(sa_stream_t *s, unsigned *rate); -int sa_stream_get_pcm_nchannels(sa_stream_t *s, int *nchannels); -int sa_stream_get_user_data(sa_stream_t *s, void **value); -int sa_stream_get_write_latency(sa_stream_t *s, size_t *nbytes); -int sa_stream_get_write_wakeup(sa_stream_t *s, size_t *nbytes); -int sa_stream_get_read_latency(sa_stream_t *s, size_t *nbytes); -int sa_stream_get_read_wakeup(sa_stream_t *s, size_t *nbytes); -int sa_stream_get_pcm_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned *n); -int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode); -int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled); -int sa_stream_get_pcm_dynamic_rate(sa_stream_t *s, int *enabled); -int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size); -int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size); -int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned *n); -int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned *n); -int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size); -int sa_stream_get_adjust_pcm_rate(sa_stream_t *s, sa_adjust_t *direction); -int sa_stream_get_adjust_pcm_nchannels(sa_stream_t *s, sa_adjust_t *direction); -int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction); +int sa_stream_get_mode(sa_stream *s, sa_mode_t *access_mode); +int sa_stream_get_codec(sa_stream *s, char **codec); +int sa_stream_get_pcm_format(sa_stream *s, sa_pcm_format_t *format); +int sa_stream_get_pcm_rate(sa_stream *s, unsigned *rate); +int sa_stream_get_pcm_nchannels(sa_stream *s, unsigned *nchannels); +int sa_stream_get_user_data(sa_stream *s, void **value); +int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes); +int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes); +int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes); +int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes); +int sa_stream_get_pcm_channel_map(sa_stream *s, sa_channel_t **map, unsigned *n); +int sa_stream_get_xrun_mode(sa_stream *s, sa_xrun_mode_t *mode); +int sa_stream_get_non_interleaved(sa_stream *s, int *enabled); +int sa_stream_get_dynamic_pcm_rate(sa_stream *s, int *enabled); +int sa_stream_get_driver(sa_stream *s, char **driver_name); +int sa_stream_get_device(sa_stream *s, char **device_name); +int sa_stream_get_read_volume(sa_stream *s, int32_t **vol, unsigned *n); +int sa_stream_get_write_volume(sa_stream *s, int32_t **vol, unsigned *n); +int sa_stream_get_adjust_pcm_rate(sa_stream *s, sa_adjust_t *direction); +int sa_stream_get_adjust_pcm_nchannels(sa_stream *s, sa_adjust_t *direction); +int sa_stream_get_adjust_pcm_format(sa_stream *s, sa_adjust_t *direction); /** Get current state of the audio device */ -int sa_stream_get_state(sa_stream_t *s, sa_state_t *state); +int sa_stream_get_state(sa_stream *s, sa_state_t *state); /** Obtain the error code */ -int sa_stream_get_event_error(sa_stream_t *s, int *error); +int sa_stream_get_event_error(sa_stream *s, int *error); /** Obtain the notification code */ -int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify); +int sa_stream_get_event_notify(sa_stream *s, sa_notify_t *notify, void **data, size_t *data_nbytes); /** sync/timing */ -int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos); +int sa_stream_get_position(sa_stream *s, sa_position_t position, int64_t *pos); -/* Blocking IO calls */ +/* IO calls */ +int sa_stream_wait(sa_stream *s, sa_event_t *event); /** Interleaved capture function */ -int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes); +int sa_stream_read(sa_stream *s, void *data, size_t nbytes); /** Non-interleaved capture function */ -int sa_stream_read_ni(sa_stream_t *s, unsigned channel, void *data, size_t nbytes); +int sa_stream_read_ni(sa_stream *s, unsigned channel, void *data, size_t nbytes); /** Interleaved playback function */ -int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes); +int sa_stream_write(sa_stream *s, const void *data, size_t nbytes); /** Non-interleaved playback function */ -int sa_stream_write_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes); +int sa_stream_write_ni(sa_stream *s, unsigned channel, const void *data, size_t nbytes); /** Interleaved playback function with seek offset */ -int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +int sa_stream_pwrite(sa_stream *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); /** Non-interleaved playback function with seek offset */ -int sa_stream_pwrite_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +int sa_stream_pwrite_ni(sa_stream *s, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); /** Query how much can be read without blocking */ -int sa_stream_get_read_size(sa_stream_t *s, size_t *nbytes); +int sa_stream_get_read_size(sa_stream *s, size_t *nbytes); /** Query how much can be written without blocking */ -int sa_stream_get_write_size(sa_stream_t *s, size_t *nbytes); +int sa_stream_get_write_size(sa_stream *s, size_t *nbytes); /* Control/xrun */ /** Resume playing after a pause */ -int sa_stream_start(sa_stream_t *s); +int sa_stream_start(sa_stream *s); /** Pause audio playback (do not empty the buffer) */ -int sa_stream_stop(sa_stream_t *s); +int sa_stream_stop(sa_stream *s); /** Block until all audio has been played */ -int sa_stream_drain(sa_stream_t *s); +int sa_stream_drain(sa_stream *s); /** Return a human readable error */ const char *sa_strerror(int code); -/* Stream properties */ +unsigned sa_stream_bytes_to_frames(sa_stream *s, size_t nbytes, int round_up); +size_t sa_stream_frames_to_bytes(sa_stream *s, unsigned nframes); + +uint64_t sa_stream_bytes_to_usec(sa_stream *s, size_t nbytes, int round_up); +size_t sa_stream_usec_to_bytes(sa_stream *s, uint64_t usec, int round_up); -/** Update meta data string properties that are attached to this stream. Takes a NULL terminated list of string key/value pairs. */ -int sa_stream_change_props(sa_stream_t *s, ...) SA_GCC_SENTINEL; +uint64_t sa_stream_frames_to_usec(sa_stream *s, unsigned nframes, int round_up); +unsigned sa_stream_usec_to_frames(sa_stream *s, uint64_t usec, int round_up); -/** Update abritrary meta data properties that are attached to this stream */ -int sa_stream_change_prop(sa_stream_t *s, const char *key, const void *data, size_t nbytes); +typedef struct sa_allocator { + void* (*malloc)(size_t size); + void* (*calloc)(size_t nmemb, size_t size); + void (*free)(void *ptr); + void* (*realloc)(void *ptr, size_t size); +} sa_allocator; -/** Remove abritrary meta data properties that are attached to this stream */ -int sa_stream_remove_prop(sa_stream_t *s, ...) SA_GCC_SENTINEL; +void sa_set_allocator(const sa_allocator *a); #ifdef __cplusplus } -- cgit