summaryrefslogtreecommitdiffstats
path: root/sydney.h
diff options
context:
space:
mode:
Diffstat (limited to 'sydney.h')
-rw-r--r--sydney.h341
1 files changed, 341 insertions, 0 deletions
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 <sys/types.h>
+#include <sys/param.h>
+#include <inttypes.h>
+
+/* 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