From 2eb6dec8e9f0114bdbad59cf8f11f197f8fdaaf3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Apr 2007 10:27:13 +0000 Subject: initial commit git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@3 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce --- sydney.h | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 sydney.h (limited to 'sydney.h') diff --git a/sydney.h b/sydney.h new file mode 100644 index 0000000..7f70add --- /dev/null +++ b/sydney.h @@ -0,0 +1,341 @@ +#ifndef foosydneyhfoo +#define foosydneyhfoo + +/* Requirements: + +- 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 +#include +#include + +/* Detect byte order, based on sys/param.h */ +#if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || defined(WIN32) +# define SA_LITTLE_ENDIAN +# undef SA_BIG_ENDIAN +#elif (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) +# undef SA_LITTLE_ENDIAN +# define SA_BIG_ENDIAN +#else +# error "Cannot determine byte order!" +#endif + +typedef struct sa_device sa_device_t; + +/** Volume that corresponds to muted in/out */ +#define SA_VOLUME_MUTED 0x80000000 + +/** Ways to express seek offsets for pread/pwrite */ +typedef enum { + SA_SEEK_RELATIVE, + SA_SEEK_ABSOLUTE, + SA_SEEK_RELATIVE_END, +} sa_seek_t; + +/** Supported formats */ +typedef enum { + SA_PCM_FORMAT_U8, + SA_PCM_FORMAT_ULAW, + SA_PCM_FORMAT_ALAW, + SA_PCM_FORMAT_S16_LE, + SA_PCM_FORMAT_S16_BE, + SA_PCM_FORMAT_S24_LE, + SA_PCM_FORMAT_S24_BE, + SA_PCM_FORMAT_S32_LE, + SA_PCM_FORMAT_S32_BE, + SA_PCM_FORMAT_FLOAT32_LE, + SA_PCM_FORMAT_FLOAT32_BE, + SA_PCM_FORMAT_MAX +} sa_pcm_format_t; + +/* Native endianness definitions for PCM */ +#ifdef SA_LITTLE_ENDIAN +#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_LE +#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_LE +#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_LE +#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_LE +#else +#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_BE +#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_BE +#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_BE +#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_BE +#endif + +#define SA_CODEC_MPEG "mpeg" +#define SA_CODEC_AC3 "ac3" +#define SA_CODEC_GSM "gsm" +#define SA_CODEC_VORBIS "vorbis" +#define SA_CODEC_SPEEX "speex" + +/** Device opening modes */ +typedef enum { + SA_MODE_RDONLY = 1, + SA_MODE_WRONLY = 2, + SA_MODE_RDWR = 3 +} sa_mode_t; + +/** Error codes */ +typedef enum { + SA_SUCCESS = 0, + SA_ERROR_NOT_SUPPORTED = -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_t; + +/** Possible events for notifications */ +typedef enum { + SA_NOTIFY_REQUEST_STOP, + SA_NOTIFY_REQUEST_START, + SA_NOTIFY_VOLUME_CHANGED_IN, + SA_NOTIFY_VOLUME_CHANGED_OUT, + SA_NOTIFY_DEVICE_CHANGED +} sa_notify_t; + +/** Classes of events */ +typedef enum { + SA_EVENT_REQUEST_IO, + SA_EVENT_INIT_THREAD, + SA_EVENT_NOTIFY, + SA_EVENT_ERROR +} sa_event_t; + +/** List of sample position queries */ +typedef enum { + SA_POSITION_WRITE_DELAY, + SA_POSITION_WRITE_HARDWARE, + SA_POSITION_WRITE_SOFTWARE, + SA_POSITION_READ_DELAY, + SA_POSITION_READ_HARDWARE, + SA_POSITION_READ_SOFTWARE, + SA_POSITION_DUPLEX_DELAY, + SA_POSITION_MAX +} sa_position_t; + +/* Channel positions */ +typedef enum { + SA_CHANNEL_MONO, + SA_CHANNEL_LEFT, + SA_CHANNEL_RIGHT, + SA_CHANNEL_CENTER, + SA_CHANNEL_FRONT_LEFT, + SA_CHANNEL_FRONT_RIGHT, + SA_CHANNEL_FRONT_CENTER, + SA_CHANNEL_REAR_LEFT, + SA_CHANNEL_REAR_RIGHT, + SA_CHANNEL_REAR_CENTER, + SA_CHANNEL_LFE, + SA_CHANNEL_FRONT_LEFT_OF_CENTER, + SA_CHANNEL_FRONT_RIGHT_OF_CENTER, + SA_CHANNEL_SIDE_LEFT, + SA_CHANNEL_SIDE_RIGHT, + SA_CHANNEL_TOP_CENTER, + SA_CHANNEL_TOP_FRONT_LEFT, + SA_CHANNEL_TOP_FRONT_RIGHT, + SA_CHANNEL_TOP_FRONT_CENTER, + SA_CHANNEL_TOP_REAR_LEFT, + SA_CHANNEL_TOP_REAR_RIGHT, + SA_CHANNEL_TOP_REAR_CENTER, + SA_CHANNEL_AUX0, + SA_CHANNEL_AUX1, + SA_CHANNEL_AUX2, + SA_CHANNEL_AUX3, + SA_CHANNEL_AUX4, + SA_CHANNEL_AUX5, + SA_CHANNEL_AUX6, + SA_CHANNEL_AUX7, + SA_CHANNEL_AUX8, + SA_CHANNEL_AUX9, + SA_CHANNEL_AUX10, + SA_CHANNEL_AUX11, + SA_CHANNEL_AUX12, + SA_CHANNEL_AUX13, + SA_CHANNEL_AUX14, + SA_CHANNEL_AUX15, + SA_CHANNEL_AUX16, + SA_CHANNEL_AUX17, + SA_CHANNEL_AUX18, + SA_CHANNEL_AUX19, + SA_CHANNEL_AUX20, + SA_CHANNEL_AUX21, + SA_CHANNEL_AUX22, + SA_CHANNEL_AUX23, + SA_CHANNEL_AUX24, + SA_CHANNEL_AUX25, + SA_CHANNEL_AUX26, + SA_CHANNEL_AUX27, + SA_CHANNEL_AUX28, + SA_CHANNEL_AUX29, + SA_CHANNEL_AUX30, + SA_CHANNEL_AUX31, + SA_CHANNEL_MAX +} sa_channel_t; + +typedef enum { + SA_STATE_INIT, + SA_STATE_RUNNING, + SA_STATE_STOPPED, + /* put more stuff */ +} sa_state_t; + +typedef enum { + SA_XRUN_MODE_STOP, + SA_XRUN_MODE_SPIN +} sa_xrun_mode_t; + +typedef enum { + SA_ADJUST_UP = 1, + SA_ADJUST_DOWN = -1, + SA_ADJUST_NONE = 0, +} sa_adjust_t; + +/** Main callback function */ +typedef int (*sa_event_callback_t)(sa_device_t *dev, sa_event_t event); + +/** Create an opaque (e.g. AC3) codec stream */ +int sa_device_create_opaque(sa_device_t **dev, const char *client_name, sa_mode_t mode, const char *codec); + +/** Normal way to open a PCM device */ +int sa_device_create_pcm(sa_device_t **dev, const char *client_name, sa_mode_t mode, sa_pcm_format_t format, unsigned rate, unsigned nchannels); + +/** Initialise the device */ +int sa_device_open(sa_device_t *dev); + +/** Close/destroy everything */ +int sa_device_destroy(sa_device_t *dev); + +/* "Soft" params */ +int sa_device_set_write_lower_watermark(sa_device_t *dev, size_t size); +int sa_device_set_read_lower_watermark(sa_device_t *dev, size_t size); + +int sa_device_set_write_upper_watermark(sa_device_t *dev, size_t size); +int sa_device_set_read_upper_watermark(sa_device_t *dev, size_t size); + +/** Set the mapping between channels and the loudspeakers */ +int sa_device_set_channel_map(sa_device_t *dev, const sa_channel_t map[]); + +/** Whether xruns cause the card to reset */ +int sa_device_set_xrun_mode(sa_device_t *dev, sa_xrun_mode_t mode); + +/** Set the device to non-interleaved mode */ +int sa_device_set_ni(sa_device_t *dev, int enable); + +/** Require dynamic sample rate */ +int sa_device_set_dsr(sa_device_t *dev, int enable); + +/** Select driver */ +int sa_device_set_driver(sa_device_t *dev, const char *driver); + +/** Start callback */ +int sa_device_start_thread(sa_device_t *dev, sa_event_callback_t *callback); + +/** Change the device connected to the stream */ +int sa_device_change_device(sa_device_t *dev, const char *device_name); + +/** volume in hundreths of dB's*/ +int sa_device_change_input_volume(sa_device_t *dev, int *vol); + +/** volume in hundreths of dB's*/ +int sa_device_change_output_volume(sa_device_t *dev, int *vol); + +/** Change the sampling rate */ +int sa_device_change_sampling_rate(sa_device_t *dev, unsigned rate); + +/** Change the name of the client application using the device */ +int sa_device_change_client_name(sa_device_t *dev, const char *client_name); + +/** Change the name of the stream being sent */ +int sa_device_change_stream_name(sa_device_t *dev, const char *stream_name); + +/** Associate opaque user data */ +int sa_device_change_user_data(sa_device_t *dev, void *value); + +/* Hardware-related. This is implementation-specific and hardware specific. */ +int sa_device_adjust_rate(sa_device_t *dev, sa_adjust_t direction); + +int sa_device_adjust_nchannels(sa_device_t *dev, sa_adjust_t direction); + +int sa_device_adjust_pcm_format(sa_device_t *dev, sa_adjust_t direction); + +/* Query functions */ + +/** Get current state of the audio device */ +int sa_device_get_state(sa_device_t *dev, sa_state_t *state); + +/** Get current sampling rate */ +int sa_device_get_sampling_rate(sa_device_t *dev, unsigned *rate); + +/** Get number of channels */ +int sa_device_get_nchannels(sa_device_t *dev, int *nchannels); + +/** Get format being used */ +int sa_device_get_pcm_format(sa_device_t *dev, sa_pcm_format_t *format); + +/** Get opaque pointer associated to the device */ +int sa_device_get_user_data(sa_device_t *dev, void **value); + +/** Obtain the error code */ +int sa_device_get_event_error(sa_device_t *dev, sa_error_t *error); + +/** Obtain the notification code */ +int sa_device_get_event_notify(sa_device_t *dev, sa_notify_t *notify); + +/** sync/timing */ +int sa_device_get_position(sa_device_t *dev, sa_position_t position, int64_t *pos); + + + + +/* Blocking IO calls */ + +/** Interleaved capture function */ +int sa_device_read(sa_device_t *dev, void *data, size_t nbytes); +/** Interleaved playback function */ +int sa_device_write(sa_device_t *dev, const void *data, size_t nbytes); + +/** Non-interleaved capture function */ +int sa_device_read_ni(sa_device_t *dev, unsigned channel, void *data, size_t nbytes); +/** Non-interleaved playback function */ +int sa_device_write_ni(sa_device_t *dev, unsigned channel, const void *data, size_t nbytes); + +/** Interleaved capture function with seek offset */ +int sa_device_pread(sa_device_t *dev, void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +/** Interleaved playback function with seek offset */ +int sa_device_pwrite(sa_device_t *dev, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence); + +/** Non-interleaved capture function with seek offset */ +int sa_device_pread_ni(sa_device_t *dev, unsigned channel, void *data, size_t nbytes, int64_t offset, sa_seek_t whence); +/** Non-interleaved playback function with seek offset */ +int sa_device_pwrite_ni(sa_device_t *dev, 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_device_get_read_size(sa_device_t *dev, size_t *size); +/** Query how much can be written without blocking */ +int sa_device_get_write_size(sa_device_t *dev, size_t *size); + + +/* Control/xrun */ + +/** Resume playing after a pause */ +int sa_device_resume(sa_device_t *dev); + +/** Pause audio playback (do not empty the buffer) */ +int sa_device_pause(sa_device_t *dev); + +/** Block until all audio has been played */ +int sa_device_drain(sa_device_t *dev); + +#endif -- cgit