From a2b28ddd5aa5e11895aa2a53df4065475c525b68 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 13 Apr 2008 00:10:04 +0000 Subject: some leftover work git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@43 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce --- src/sydney.h | 147 +++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 92 insertions(+), 55 deletions(-) (limited to 'src/sydney.h') diff --git a/src/sydney.h b/src/sydney.h index eb1a7ec..58324ca 100644 --- a/src/sydney.h +++ b/src/sydney.h @@ -5,15 +5,23 @@ extern "C" { #endif -/* Requirements: +/* + 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. -- 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) */ #include @@ -22,15 +30,16 @@ async-signal safe. /* Detect byte order, based on sys/param.h */ #if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || defined(WIN32) -# define SA_LITTLE_ENDIAN 1 -# undef SA_BIG_ENDIAN +#define SA_LITTLE_ENDIAN 1 +#undef SA_BIG_ENDIAN #elif (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) -# undef SA_LITTLE_ENDIAN -# define SA_BIG_ENDIAN 1 +#undef SA_LITTLE_ENDIAN +#define SA_BIG_ENDIAN 1 #else -# error "Cannot determine byte order!" +#error "Cannot determine byte order!" #endif +/** Stream object */ typedef struct sa_stream sa_stream_t; /** Volume that corresponds to muted in/out */ @@ -96,7 +105,7 @@ typedef enum { } sa_mode_t; /** Error codes */ -typedef enum { +enum { SA_SUCCESS = 0, SA_ERROR_NOT_SUPPORTED = -1, SA_ERROR_INVALID = -2, @@ -112,7 +121,7 @@ typedef enum { SA_ERROR_NO_DATA = -11, SA_ERROR_NO_SPACE = -12, _SA_ERROR_MAX = -13 -} sa_error_t; +}; /** Possible events for notifications */ typedef enum { @@ -130,6 +139,7 @@ typedef enum { SA_EVENT_INIT_THREAD, SA_EVENT_NOTIFY, SA_EVENT_ERROR, + SA_EVENT_XRUN, _SA_EVENT_MAX } sa_event_t; @@ -208,6 +218,7 @@ typedef enum { SA_STATE_INIT, SA_STATE_RUNNING, SA_STATE_STOPPED, + SA_STATE_DRAINING, /* put more stuff */ _SA_STATE_MAX } sa_state_t; @@ -215,6 +226,7 @@ typedef enum { typedef enum { SA_XRUN_MODE_STOP, SA_XRUN_MODE_SPIN, + SA_XRUN_MODE_FILL, _SA_XRUN_MODE_MAX } sa_xrun_mode_t; @@ -224,18 +236,31 @@ typedef enum { SA_ADJUST_NONE = 0 } sa_adjust_t; -/* Some kind of meta information. */ -#define SA_META_CLIENT_NAME "sydney.client-name" /* utf-8 */ -#define SA_META_PROCESS_ID "sydney.process-id" /* getpid() */ -#define SA_META_LANGUAGE "sydney.language" /* de_DE and similar */ - -/* Some kind of meta information. Not filled in */ -#define SA_META_STREAM_NAME "sydney.stream-name" /* utf-8 */ -#define SA_META_ICON_NAME "sydney.icon-name" /* file name (no slashes) */ -#define SA_META_ICON_PNG "sydney.icon-png" /* PNG blob */ -#define SA_META_ROLE "sydney.role" /* one of: "music", "phone", "game", "event" */ -#define SA_META_X11_DISPLAY "sydney.x11-display" /* X11 display */ -#define SA_META_X11_WINDOW "sydney.x11-window" /* X11 window id */ +/** 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); @@ -252,11 +277,11 @@ int sa_stream_open(sa_stream_t *s); /** Close/destroy everything */ int sa_stream_destroy(sa_stream_t *s); -/* "Soft" params */ -/* int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size); */ -/* int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size); */ -/* int sa_stream_set_write_user_size(sa_stream_t *s, size_t size); */ -/* int sa_stream_set_read_user_size(sa_stream_t *s, size_t size); */ +/* 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); /** 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); @@ -270,13 +295,19 @@ int sa_stream_set_non_interleaved(sa_stream_t *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); + /** Select driver */ int sa_stream_set_driver(sa_stream_t *s, const char *driver); -/** Start callback */ +/** Start callback thread */ int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback); -/** Start callback */ +/** Start callback thread */ int sa_stream_stop_thread(sa_stream_t *s); /** Change the device connected to the stream */ @@ -291,9 +322,6 @@ int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned /** Change the sampling rate */ int sa_stream_change_rate(sa_stream_t *s, unsigned rate); -/** Change some meta data that is attached to the stream */ -int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size); - /** Associate opaque user data */ int sa_stream_change_user_data(sa_stream_t *s, const void *value); @@ -301,39 +329,37 @@ int sa_stream_change_user_data(sa_stream_t *s, const void *value); 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_watermarks(sa_stream_t *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_rate(sa_stream_t *s, unsigned *rate); -int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels); +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_lower_watermark(sa_stream_t *s, size_t *size); */ -/* int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size); */ -/* int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size); */ -/* int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size); */ -int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned *n); +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_dynamic_rate(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_rate(sa_stream_t *s, sa_adjust_t *direction); -int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction); +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_adjust_watermarks(sa_stream_t *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); /** Obtain the error code */ -int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error); +int sa_stream_get_event_error(sa_stream_t *s, int *error); /** Obtain the notification code */ int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify); @@ -360,18 +386,18 @@ int sa_stream_pwrite_ni(sa_stream_t *s, unsigned channel, const void *data, size /** Query how much can be read without blocking */ -int sa_stream_get_read_size(sa_stream_t *s, size_t *size); +int sa_stream_get_read_size(sa_stream_t *s, size_t *nbytes); /** Query how much can be written without blocking */ -int sa_stream_get_write_size(sa_stream_t *s, size_t *size); +int sa_stream_get_write_size(sa_stream_t *s, size_t *nbytes); /* Control/xrun */ /** Resume playing after a pause */ -int sa_stream_resume(sa_stream_t *s); +int sa_stream_start(sa_stream_t *s); /** Pause audio playback (do not empty the buffer) */ -int sa_stream_pause(sa_stream_t *s); +int sa_stream_stop(sa_stream_t *s); /** Block until all audio has been played */ int sa_stream_drain(sa_stream_t *s); @@ -379,6 +405,17 @@ int sa_stream_drain(sa_stream_t *s); /** Return a human readable error */ const char *sa_strerror(int code); +/* Stream properties */ + +/** 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; + +/** 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); + +/** Remove abritrary meta data properties that are attached to this stream */ +int sa_stream_remove_prop(sa_stream_t *s, ...) SA_GCC_SENTINEL; + #ifdef __cplusplus } #endif -- cgit