Home | History | Annotate | Download | only in pcm
      1 /*
      2  *  PCM Interface - local header file
      3  *  Copyright (c) 2000 by Jaroslav Kysela <perex (at) perex.cz>
      4  *                        Abramo Bagnara <abramo (at) alsa-project.org>
      5  *
      6  *
      7  *   This library is free software; you can redistribute it and/or modify
      8  *   it under the terms of the GNU Lesser General Public License as
      9  *   published by the Free Software Foundation; either version 2.1 of
     10  *   the License, or (at your option) any later version.
     11  *
     12  *   This program is distributed in the hope that it will be useful,
     13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  *   GNU Lesser General Public License for more details.
     16  *
     17  *   You should have received a copy of the GNU Lesser General Public
     18  *   License along with this library; if not, write to the Free Software
     19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     20  *
     21  */
     22 
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <limits.h>
     26 #include <sys/uio.h>
     27 
     28 #define _snd_mask sndrv_mask
     29 #define _snd_pcm_access_mask _snd_mask
     30 #define _snd_pcm_format_mask _snd_mask
     31 #define _snd_pcm_subformat_mask _snd_mask
     32 
     33 #include "local.h"
     34 
     35 #define SND_INTERVAL_INLINE
     36 #include "interval.h"
     37 
     38 #define SND_MASK_INLINE
     39 #include "mask.h"
     40 
     41 typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
     42 #define SND_PCM_HW_PARAM_ACCESS SNDRV_PCM_HW_PARAM_ACCESS
     43 #define SND_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_FIRST_MASK
     44 #define SND_PCM_HW_PARAM_FORMAT SNDRV_PCM_HW_PARAM_FORMAT
     45 #define SND_PCM_HW_PARAM_SUBFORMAT SNDRV_PCM_HW_PARAM_SUBFORMAT
     46 #define SND_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_LAST_MASK
     47 #define SND_PCM_HW_PARAM_SAMPLE_BITS SNDRV_PCM_HW_PARAM_SAMPLE_BITS
     48 #define SND_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_FIRST_INTERVAL
     49 #define SND_PCM_HW_PARAM_FRAME_BITS SNDRV_PCM_HW_PARAM_FRAME_BITS
     50 #define SND_PCM_HW_PARAM_CHANNELS SNDRV_PCM_HW_PARAM_CHANNELS
     51 #define SND_PCM_HW_PARAM_RATE SNDRV_PCM_HW_PARAM_RATE
     52 #define SND_PCM_HW_PARAM_PERIOD_TIME SNDRV_PCM_HW_PARAM_PERIOD_TIME
     53 #define SND_PCM_HW_PARAM_PERIOD_SIZE SNDRV_PCM_HW_PARAM_PERIOD_SIZE
     54 #define SND_PCM_HW_PARAM_PERIOD_BYTES SNDRV_PCM_HW_PARAM_PERIOD_BYTES
     55 #define SND_PCM_HW_PARAM_PERIODS SNDRV_PCM_HW_PARAM_PERIODS
     56 #define SND_PCM_HW_PARAM_BUFFER_TIME SNDRV_PCM_HW_PARAM_BUFFER_TIME
     57 #define SND_PCM_HW_PARAM_BUFFER_SIZE SNDRV_PCM_HW_PARAM_BUFFER_SIZE
     58 #define SND_PCM_HW_PARAM_BUFFER_BYTES SNDRV_PCM_HW_PARAM_BUFFER_BYTES
     59 #define SND_PCM_HW_PARAM_TICK_TIME SNDRV_PCM_HW_PARAM_TICK_TIME
     60 #define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL
     61 #define SND_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_LAST_MASK
     62 #define SND_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_FIRST_MASK
     63 #define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL
     64 #define SND_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_FIRST_INTERVAL
     65 
     66 /** device accepts mmaped access */
     67 #define SND_PCM_INFO_MMAP SNDRV_PCM_INFO_MMAP
     68 /** device accepts  mmaped access with sample resolution */
     69 #define SND_PCM_INFO_MMAP_VALID SNDRV_PCM_INFO_MMAP_VALID
     70 /** device is doing double buffering */
     71 #define SND_PCM_INFO_DOUBLE SNDRV_PCM_INFO_DOUBLE
     72 /** device transfers samples in batch */
     73 #define SND_PCM_INFO_BATCH SNDRV_PCM_INFO_BATCH
     74 /** device accepts interleaved samples */
     75 #define SND_PCM_INFO_INTERLEAVED SNDRV_PCM_INFO_INTERLEAVED
     76 /** device accepts non-interleaved samples */
     77 #define SND_PCM_INFO_NONINTERLEAVED SNDRV_PCM_INFO_NONINTERLEAVED
     78 /** device accepts complex sample organization */
     79 #define SND_PCM_INFO_COMPLEX SNDRV_PCM_INFO_COMPLEX
     80 /** device is capable block transfers */
     81 #define SND_PCM_INFO_BLOCK_TRANSFER SNDRV_PCM_INFO_BLOCK_TRANSFER
     82 /** device can detect DAC/ADC overrange */
     83 #define SND_PCM_INFO_OVERRANGE SNDRV_PCM_INFO_OVERRANGE
     84 /** device supports resume */
     85 #define SND_PCM_INFO_RESUME SNDRV_PCM_INFO_RESUME
     86 /** device is capable to pause */
     87 #define SND_PCM_INFO_PAUSE SNDRV_PCM_INFO_PAUSE
     88 /** device can do only half duplex */
     89 #define SND_PCM_INFO_HALF_DUPLEX SNDRV_PCM_INFO_HALF_DUPLEX
     90 /** device can do only joint duplex (same parameters) */
     91 #define SND_PCM_INFO_JOINT_DUPLEX SNDRV_PCM_INFO_JOINT_DUPLEX
     92 /** device can do a kind of synchronized start */
     93 #define SND_PCM_INFO_SYNC_START SNDRV_PCM_INFO_SYNC_START
     94 
     95 #define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE
     96 #define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER
     97 
     98 #define SND_PCM_INFO_MONOTONIC	0x80000000
     99 
    100 typedef struct _snd_pcm_rbptr {
    101 	snd_pcm_t *master;
    102 	volatile snd_pcm_uframes_t *ptr;
    103 	int fd;
    104 	off_t offset;
    105 	int link_dst_count;
    106 	snd_pcm_t **link_dst;
    107 	void *private_data;
    108 	void (*changed)(snd_pcm_t *pcm, snd_pcm_t *src);
    109 } snd_pcm_rbptr_t;
    110 
    111 typedef struct _snd_pcm_channel_info {
    112 	unsigned int channel;
    113 	void *addr;			/* base address of channel samples */
    114 	unsigned int first;		/* offset to first sample in bits */
    115 	unsigned int step;		/* samples distance in bits */
    116 	enum { SND_PCM_AREA_SHM, SND_PCM_AREA_MMAP, SND_PCM_AREA_LOCAL } type;
    117 	union {
    118 		struct {
    119 			struct snd_shm_area *area;
    120 			int shmid;
    121 		} shm;
    122 		struct {
    123 			int fd;
    124 			off_t offset;
    125 		} mmap;
    126 	} u;
    127 	char reserved[64];
    128 } snd_pcm_channel_info_t;
    129 
    130 typedef struct {
    131 	int (*close)(snd_pcm_t *pcm);
    132 	int (*nonblock)(snd_pcm_t *pcm, int nonblock);
    133 	int (*async)(snd_pcm_t *pcm, int sig, pid_t pid);
    134 	int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
    135 	int (*hw_refine)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    136 	int (*hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    137 	int (*hw_free)(snd_pcm_t *pcm);
    138 	int (*sw_params)(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
    139 	int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
    140 	void (*dump)(snd_pcm_t *pcm, snd_output_t *out);
    141 	int (*mmap)(snd_pcm_t *pcm);
    142 	int (*munmap)(snd_pcm_t *pcm);
    143 } snd_pcm_ops_t;
    144 
    145 typedef struct {
    146 	int (*status)(snd_pcm_t *pcm, snd_pcm_status_t *status);
    147 	int (*prepare)(snd_pcm_t *pcm);
    148 	int (*reset)(snd_pcm_t *pcm);
    149 	int (*start)(snd_pcm_t *pcm);
    150 	int (*drop)(snd_pcm_t *pcm);
    151 	int (*drain)(snd_pcm_t *pcm);
    152 	int (*pause)(snd_pcm_t *pcm, int enable);
    153 	snd_pcm_state_t (*state)(snd_pcm_t *pcm);
    154 	int (*hwsync)(snd_pcm_t *pcm);
    155 	int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
    156 	int (*resume)(snd_pcm_t *pcm);
    157 	int (*link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
    158 	int (*link_slaves)(snd_pcm_t *pcm, snd_pcm_t *master);
    159 	int (*unlink)(snd_pcm_t *pcm);
    160 	snd_pcm_sframes_t (*rewindable)(snd_pcm_t *pcm);
    161 	snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    162 	snd_pcm_sframes_t (*forwardable)(snd_pcm_t *pcm);
    163 	snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    164 	snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
    165 	snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
    166 	snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
    167 	snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
    168 	snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
    169 	snd_pcm_sframes_t (*mmap_commit)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size);
    170 	int (*htimestamp)(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
    171 	int (*poll_descriptors_count)(snd_pcm_t *pcm);
    172 	int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
    173 	int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
    174 } snd_pcm_fast_ops_t;
    175 
    176 struct _snd_pcm {
    177 	void *dl_handle;
    178 	char *name;
    179 	snd_pcm_type_t type;
    180 	snd_pcm_stream_t stream;
    181 	int mode;
    182 	int poll_fd_count;
    183 	int poll_fd;
    184 	unsigned short poll_events;
    185 	int setup: 1,
    186 	    monotonic: 1;
    187 	snd_pcm_access_t access;	/* access mode */
    188 	snd_pcm_format_t format;	/* SND_PCM_FORMAT_* */
    189 	snd_pcm_subformat_t subformat;	/* subformat */
    190 	unsigned int channels;		/* channels */
    191 	unsigned int rate;		/* rate in Hz */
    192 	snd_pcm_uframes_t period_size;
    193 	unsigned int period_time;	/* period duration */
    194 	snd_interval_t periods;
    195 	snd_pcm_tstamp_t tstamp_mode;	/* timestamp mode */
    196 	unsigned int period_step;
    197 	snd_pcm_uframes_t avail_min;	/* min avail frames for wakeup */
    198 	int period_event;
    199 	snd_pcm_uframes_t start_threshold;
    200 	snd_pcm_uframes_t stop_threshold;
    201 	snd_pcm_uframes_t silence_threshold;	/* Silence filling happens when
    202 					   noise is nearest than this */
    203 	snd_pcm_uframes_t silence_size;	/* Silence filling size */
    204 	snd_pcm_uframes_t boundary;	/* pointers wrap point */
    205 	unsigned int info;		/* Info for returned setup */
    206 	unsigned int msbits;		/* used most significant bits */
    207 	unsigned int rate_num;		/* rate numerator */
    208 	unsigned int rate_den;		/* rate denominator */
    209 	unsigned int hw_flags;		/* actual hardware flags */
    210 	snd_pcm_uframes_t fifo_size;	/* chip FIFO size in frames */
    211 	snd_pcm_uframes_t buffer_size;
    212 	snd_interval_t buffer_time;
    213 	unsigned int sample_bits;
    214 	unsigned int frame_bits;
    215 	snd_pcm_rbptr_t appl;
    216 	snd_pcm_rbptr_t hw;
    217 	snd_pcm_uframes_t min_align;
    218 	unsigned int mmap_rw: 1;	/* use always mmapped buffer */
    219 	unsigned int mmap_shadow: 1;	/* don't call actual mmap,
    220 					 * use the mmaped buffer of the slave
    221 					 */
    222 	unsigned int donot_close: 1;	/* don't close this PCM */
    223 	snd_pcm_channel_info_t *mmap_channels;
    224 	snd_pcm_channel_area_t *running_areas;
    225 	snd_pcm_channel_area_t *stopped_areas;
    226 	const snd_pcm_ops_t *ops;
    227 	const snd_pcm_fast_ops_t *fast_ops;
    228 	snd_pcm_t *op_arg;
    229 	snd_pcm_t *fast_op_arg;
    230 	void *private_data;
    231 	struct list_head async_handlers;
    232 };
    233 
    234 /* make local functions really local */
    235 /* Grrr, these cannot be local - a bad aserver uses them!
    236 #define snd_pcm_async \
    237 	snd1_pcm_async
    238 #define snd_pcm_mmap \
    239 	snd1_pcm_mmap
    240 #define snd_pcm_munmap \
    241 	snd1_pcm_munmap
    242 #define snd_pcm_hw_refine \
    243 	snd1_pcm_hw_refine
    244 */
    245 #define snd_pcm_new \
    246 	snd1_pcm_new
    247 #define snd_pcm_free \
    248 	snd1_pcm_free
    249 #define snd_pcm_areas_from_buf \
    250 	snd1_pcm_areas_from_buf
    251 #define snd_pcm_areas_from_bufs \
    252 	snd1_pcm_areas_from_bufs
    253 #define snd_pcm_open_named_slave \
    254 	snd1_pcm_open_named_slave
    255 #define snd_pcm_conf_generic_id \
    256 	snd1_pcm_conf_generic_id
    257 #define snd_pcm_hw_open_fd \
    258 	snd1_pcm_hw_open_fd
    259 #define snd_pcm_wait_nocheck \
    260 	snd1_pcm_wait_nocheck
    261 #define snd_pcm_rate_get_default_converter \
    262 	snd1_pcm_rate_get_default_converter
    263 #define snd_pcm_set_hw_ptr \
    264 	snd1_pcm_set_hw_ptr
    265 #define snd_pcm_set_appl_ptr \
    266 	snd1_pcm_set_appl_ptr
    267 #define snd_pcm_link_hw_ptr \
    268 	snd1_pcm_link_hw_ptr
    269 #define snd_pcm_link_appl_ptr \
    270 	snd1_pcm_link_appl_ptr
    271 #define snd_pcm_unlink_hw_ptr \
    272 	snd1_pcm_unlink_hw_ptr
    273 #define snd_pcm_unlink_appl_ptr \
    274 	snd1_pcm_unlink_appl_ptr
    275 #define snd_pcm_mmap_appl_ptr \
    276 	snd1_pcm_mmap_appl_ptr
    277 #define snd_pcm_mmap_appl_backward \
    278 	snd1_pcm_mmap_appl_backward
    279 #define snd_pcm_mmap_appl_forward \
    280 	snd1_pcm_mmap_appl_forward
    281 #define snd_pcm_mmap_hw_backward \
    282 	snd1_pcm_mmap_hw_backward
    283 #define snd_pcm_mmap_hw_forward \
    284 	snd1_pcm_mmap_hw_forward
    285 #define snd_pcm_read_areas \
    286 	snd1_pcm_read_areas
    287 #define snd_pcm_write_areas \
    288 	snd1_pcm_write_areas
    289 #define snd_pcm_read_mmap \
    290 	snd1_pcm_read_mmap
    291 #define snd_pcm_write_mmap \
    292 	snd1_pcm_write_mmap
    293 #define snd_pcm_channel_info_shm \
    294 	snd1_pcm_channel_info_shm
    295 #define snd_pcm_hw_refine_soft \
    296 	snd1_pcm_hw_refine_soft
    297 #define snd_pcm_hw_refine_slave \
    298 	snd1_pcm_hw_refine_slave
    299 #define snd_pcm_hw_params_slave \
    300 	snd1_pcm_hw_params_slave
    301 #define snd_pcm_hw_param_refine_near \
    302 	snd1_pcm_hw_param_refine_near
    303 #define snd_pcm_hw_param_refine_multiple \
    304 	snd1_pcm_hw_param_refine_multiple
    305 #define snd_pcm_hw_param_empty \
    306 	snd1_pcm_hw_param_empty
    307 #define snd_pcm_hw_param_always_eq \
    308 	snd1_pcm_hw_param_always_eq
    309 #define snd_pcm_hw_param_never_eq \
    310 	snd1_pcm_hw_param_never_eq
    311 #define snd_pcm_hw_param_get_mask \
    312 	snd1_pcm_hw_param_get_mask
    313 #define snd_pcm_hw_param_get_interval \
    314 	snd1_pcm_hw_param_get_interval
    315 #define snd_pcm_hw_param_any \
    316 	snd1_pcm_hw_param_any
    317 #define snd_pcm_hw_param_set_integer \
    318 	snd1_pcm_hw_param_set_integer
    319 #define snd_pcm_hw_param_set_first \
    320 	snd1_pcm_hw_param_set_first
    321 #define snd_pcm_hw_param_set_last \
    322 	snd1_pcm_hw_param_set_last
    323 #define snd_pcm_hw_param_set_near \
    324 	snd1_pcm_hw_param_set_near
    325 #define snd_pcm_hw_param_set_min \
    326 	snd1_pcm_hw_param_set_min
    327 #define snd_pcm_hw_param_set_max \
    328 	snd1_pcm_hw_param_set_max
    329 #define snd_pcm_hw_param_set_minmax \
    330 	snd1_pcm_hw_param_set_minmax
    331 #define snd_pcm_hw_param_set \
    332 	snd1_pcm_hw_param_set
    333 #define snd_pcm_hw_param_set_mask \
    334 	snd1_pcm_hw_param_set_mask
    335 #define snd_pcm_hw_param_get \
    336 	snd1_pcm_hw_param_get
    337 #define snd_pcm_hw_param_get_min \
    338 	snd1_pcm_hw_param_get_min
    339 #define snd_pcm_hw_param_get_max \
    340 	snd1_pcm_hw_param_get_max
    341 #define snd_pcm_hw_param_name		\
    342 	snd1_pcm_hw_param_name
    343 
    344 int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
    345 		snd_pcm_stream_t stream, int mode);
    346 int snd_pcm_free(snd_pcm_t *pcm);
    347 
    348 void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf);
    349 void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs);
    350 
    351 int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid);
    352 int snd_pcm_mmap(snd_pcm_t *pcm);
    353 int snd_pcm_munmap(snd_pcm_t *pcm);
    354 int snd_pcm_mmap_ready(snd_pcm_t *pcm);
    355 void snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset);
    356 void snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset);
    357 void snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
    358 void snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
    359 void snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
    360 void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave);
    361 snd_pcm_sframes_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset);
    362 void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    363 void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    364 void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    365 void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    366 
    367 snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
    368 snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
    369 snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
    370 snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
    371 
    372 typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
    373 						       const snd_pcm_channel_area_t *areas,
    374 						       snd_pcm_uframes_t offset,
    375 						       snd_pcm_uframes_t size);
    376 
    377 snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
    378 				     snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
    379 				     snd_pcm_xfer_areas_func_t func);
    380 snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
    381 				      snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
    382 				      snd_pcm_xfer_areas_func_t func);
    383 snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
    384 				    snd_pcm_uframes_t size);
    385 snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
    386 				     snd_pcm_uframes_t size);
    387 static inline int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
    388 {
    389 	return pcm->ops->channel_info(pcm, info);
    390 }
    391 int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid);
    392 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm);
    393 #define _snd_pcm_link_descriptor _snd_pcm_poll_descriptor /* FIXME */
    394 #define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor /* FIXME */
    395 
    396 /* handle special error cases */
    397 static inline int snd_pcm_check_error(snd_pcm_t *pcm, int err)
    398 {
    399 	if (err == -EINTR) {
    400 		switch (snd_pcm_state(pcm)) {
    401 		case SND_PCM_STATE_XRUN:
    402 			return -EPIPE;
    403 		case SND_PCM_STATE_SUSPENDED:
    404 			return -ESTRPIPE;
    405 		case SND_PCM_STATE_DISCONNECTED:
    406 			return -ENODEV;
    407 		default:
    408 			break;
    409 		}
    410 	}
    411 	return err;
    412 }
    413 
    414 static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
    415 {
    416 	snd_pcm_sframes_t avail;
    417 	avail = *pcm->hw.ptr + pcm->buffer_size - *pcm->appl.ptr;
    418 	if (avail < 0)
    419 		avail += pcm->boundary;
    420 	else if ((snd_pcm_uframes_t) avail >= pcm->boundary)
    421 		avail -= pcm->boundary;
    422 	return avail;
    423 }
    424 
    425 static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm)
    426 {
    427 	snd_pcm_sframes_t avail;
    428 	avail = *pcm->hw.ptr - *pcm->appl.ptr;
    429 	if (avail < 0)
    430 		avail += pcm->boundary;
    431 	return avail;
    432 }
    433 
    434 static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
    435 {
    436 	if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
    437 		return snd_pcm_mmap_playback_avail(pcm);
    438 	else
    439 		return snd_pcm_mmap_capture_avail(pcm);
    440 }
    441 
    442 static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)
    443 {
    444 	return pcm->buffer_size - snd_pcm_mmap_playback_avail(pcm);
    445 }
    446 
    447 static inline snd_pcm_sframes_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm)
    448 {
    449 	return pcm->buffer_size - snd_pcm_mmap_capture_avail(pcm);
    450 }
    451 
    452 static inline snd_pcm_sframes_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
    453 {
    454 	snd_pcm_sframes_t avail;
    455 	avail = *pcm->hw.ptr - *pcm->appl.ptr;
    456 	if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
    457 		avail += pcm->buffer_size;
    458 	if (avail < 0)
    459 		avail += pcm->boundary;
    460 	return pcm->buffer_size - avail;
    461 }
    462 
    463 static inline const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
    464 {
    465 	if (pcm->stopped_areas &&
    466 	    snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING)
    467 		return pcm->stopped_areas;
    468 	return pcm->running_areas;
    469 }
    470 
    471 static inline snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
    472 {
    473         assert(pcm);
    474 	return *pcm->appl.ptr % pcm->buffer_size;
    475 }
    476 
    477 static inline snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
    478 {
    479         assert(pcm);
    480 	return *pcm->hw.ptr % pcm->buffer_size;
    481 }
    482 
    483 static inline snd_pcm_uframes_t snd_pcm_mmap_playback_delay(snd_pcm_t *pcm)
    484 {
    485 	return snd_pcm_mmap_playback_hw_avail(pcm);
    486 }
    487 
    488 static inline snd_pcm_uframes_t snd_pcm_mmap_capture_delay(snd_pcm_t *pcm)
    489 {
    490 	return snd_pcm_mmap_capture_hw_avail(pcm);
    491 }
    492 
    493 static inline snd_pcm_sframes_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
    494 {
    495 	if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
    496 		return snd_pcm_mmap_playback_delay(pcm);
    497 	else
    498 		return snd_pcm_mmap_capture_delay(pcm);
    499 }
    500 
    501 static inline void *snd_pcm_channel_area_addr(const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset)
    502 {
    503 	unsigned int bitofs = area->first + area->step * offset;
    504 	assert(bitofs % 8 == 0);
    505 	return (char *) area->addr + bitofs / 8;
    506 }
    507 
    508 static inline unsigned int snd_pcm_channel_area_step(const snd_pcm_channel_area_t *area)
    509 {
    510 	assert(area->step % 8 == 0);
    511 	return area->step / 8;
    512 }
    513 
    514 static inline snd_pcm_sframes_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
    515 {
    516 	return pcm->fast_ops->writei(pcm->fast_op_arg, buffer, size);
    517 }
    518 
    519 static inline snd_pcm_sframes_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
    520 {
    521 	return pcm->fast_ops->writen(pcm->fast_op_arg, bufs, size);
    522 }
    523 
    524 static inline snd_pcm_sframes_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
    525 {
    526 	return pcm->fast_ops->readi(pcm->fast_op_arg, buffer, size);
    527 }
    528 
    529 static inline snd_pcm_sframes_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
    530 {
    531 	return pcm->fast_ops->readn(pcm->fast_op_arg, bufs, size);
    532 }
    533 
    534 static inline int muldiv(int a, int b, int c, int *r)
    535 {
    536 	int64_t n = (int64_t)a * b;
    537 	int64_t v = n / c;
    538 	if (v > INT_MAX) {
    539 		*r = 0;
    540 		return INT_MAX;
    541 	}
    542 	if (v < INT_MIN) {
    543 		*r = 0;
    544 		return INT_MIN;
    545 	}
    546 	*r = n % c;
    547 	return v;
    548 }
    549 
    550 static inline int muldiv_down(int a, int b, int c)
    551 {
    552 	int64_t v = (int64_t)a * b / c;
    553 	if (v > INT_MAX) {
    554 		return INT_MAX;
    555 	}
    556 	if (v < INT_MIN) {
    557 		return INT_MIN;
    558 	}
    559 	return v;
    560 }
    561 
    562 static inline int muldiv_near(int a, int b, int c)
    563 {
    564 	int r;
    565 	int n = muldiv(a, b, c, &r);
    566 	if (r >= (c + 1) / 2)
    567 		n++;
    568 	return n;
    569 }
    570 
    571 int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    572 int _snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    573 int snd_pcm_hw_refine_soft(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    574 int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    575 			    int (*cprepare)(snd_pcm_t *pcm,
    576 					    snd_pcm_hw_params_t *params),
    577 			    int (*cchange)(snd_pcm_t *pcm,
    578 					   snd_pcm_hw_params_t *params,
    579 					   snd_pcm_hw_params_t *sparams),
    580 			    int (*sprepare)(snd_pcm_t *pcm,
    581 					    snd_pcm_hw_params_t *params),
    582 			    int (*schange)(snd_pcm_t *pcm,
    583 					   snd_pcm_hw_params_t *params,
    584 					   snd_pcm_hw_params_t *sparams),
    585 			    int (*srefine)(snd_pcm_t *pcm,
    586 					   snd_pcm_hw_params_t *sparams));
    587 int snd_pcm_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    588 			    int (*cchange)(snd_pcm_t *pcm,
    589 					   snd_pcm_hw_params_t *params,
    590 					   snd_pcm_hw_params_t *sparams),
    591 			    int (*sprepare)(snd_pcm_t *pcm,
    592 					    snd_pcm_hw_params_t *params),
    593 			    int (*schange)(snd_pcm_t *pcm,
    594 					   snd_pcm_hw_params_t *params,
    595 					   snd_pcm_hw_params_t *sparams),
    596 			    int (*sparams)(snd_pcm_t *pcm,
    597 					   snd_pcm_hw_params_t *sparams));
    598 
    599 
    600 void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
    601 void _snd_pcm_hw_param_set_empty(snd_pcm_hw_params_t *params,
    602 				 snd_pcm_hw_param_t var);
    603 int _snd_pcm_hw_param_set_interval(snd_pcm_hw_params_t *params,
    604 				   snd_pcm_hw_param_t var,
    605 				   const snd_interval_t *val);
    606 int _snd_pcm_hw_param_set_mask(snd_pcm_hw_params_t *params,
    607 			   snd_pcm_hw_param_t var, const snd_mask_t *mask);
    608 int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
    609 			    snd_pcm_hw_param_t var);
    610 int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
    611 			   snd_pcm_hw_param_t var);
    612 int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
    613 			  snd_pcm_hw_param_t var, unsigned int val, int dir);
    614 static inline int _snd_pcm_hw_params_set_format(snd_pcm_hw_params_t *params,
    615 						snd_pcm_format_t val)
    616 {
    617 	return _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_FORMAT,
    618 				     (unsigned long) val, 0);
    619 }
    620 
    621 static inline int _snd_pcm_hw_params_set_subformat(snd_pcm_hw_params_t *params,
    622 				     snd_pcm_subformat_t val)
    623 {
    624 	return _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
    625 				     (unsigned long) val, 0);
    626 }
    627 
    628 int _snd_pcm_hw_param_set_min(snd_pcm_hw_params_t *params,
    629 			      snd_pcm_hw_param_t var, unsigned int val, int dir);
    630 int _snd_pcm_hw_param_set_max(snd_pcm_hw_params_t *params,
    631 			      snd_pcm_hw_param_t var, unsigned int val, int dir);
    632 int _snd_pcm_hw_param_set_minmax(snd_pcm_hw_params_t *params,
    633 				 snd_pcm_hw_param_t var,
    634 				 unsigned int min, int mindir,
    635 				 unsigned int max, int maxdir);
    636 int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
    637 			     snd_pcm_hw_param_t var,
    638 			     const snd_pcm_hw_params_t *src);
    639 int _snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
    640 			      unsigned int vars,
    641 			      const snd_pcm_hw_params_t *src);
    642 int snd_pcm_hw_param_refine_near(snd_pcm_t *pcm,
    643 				 snd_pcm_hw_params_t *params,
    644 				 snd_pcm_hw_param_t var,
    645 				 const snd_pcm_hw_params_t *src);
    646 int snd_pcm_hw_param_refine_multiple(snd_pcm_t *pcm,
    647 				     snd_pcm_hw_params_t *params,
    648 				     snd_pcm_hw_param_t var,
    649 				     const snd_pcm_hw_params_t *src);
    650 int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
    651 			   snd_pcm_hw_param_t var);
    652 int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
    653 			       snd_pcm_hw_param_t var,
    654 			       const snd_pcm_hw_params_t *params1);
    655 int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
    656 			      snd_pcm_hw_param_t var,
    657 			      const snd_pcm_hw_params_t *params1);
    658 const snd_mask_t *snd_pcm_hw_param_get_mask(const snd_pcm_hw_params_t *params,
    659 					      snd_pcm_hw_param_t var);
    660 const snd_interval_t *snd_pcm_hw_param_get_interval(const snd_pcm_hw_params_t *params,
    661 						      snd_pcm_hw_param_t var);
    662 
    663 int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    664 			 snd_pcm_hw_param_t var);
    665 int snd_pcm_hw_param_set_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    666 				 snd_set_mode_t mode,
    667 				 snd_pcm_hw_param_t var);
    668 int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    669 			       snd_pcm_hw_param_t var, unsigned int *rval, int *dir);
    670 int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    671 			      snd_pcm_hw_param_t var, unsigned int *rval, int *dir);
    672 int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    673 			      snd_pcm_hw_param_t var, unsigned int *val, int *dir);
    674 int snd_pcm_hw_param_set_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    675 			     snd_set_mode_t mode,
    676 			     snd_pcm_hw_param_t var,
    677 			     unsigned int *val, int *dir);
    678 int snd_pcm_hw_param_set_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    679 			     snd_set_mode_t mode,
    680 			     snd_pcm_hw_param_t var, unsigned int *val, int *dir);
    681 int snd_pcm_hw_param_set_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    682 				snd_set_mode_t mode,
    683 				snd_pcm_hw_param_t var,
    684 				unsigned int *min, int *mindir,
    685 				unsigned int *max, int *maxdir);
    686 int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    687 			 snd_set_mode_t mode,
    688 			 snd_pcm_hw_param_t var, unsigned int val, int dir);
    689 int snd_pcm_hw_param_set_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
    690 			      snd_set_mode_t mode,
    691 			      snd_pcm_hw_param_t var, const snd_mask_t *mask);
    692 int snd_pcm_hw_param_get(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var,
    693 			 unsigned int *val, int *dir);
    694 int snd_pcm_hw_param_get_min(const snd_pcm_hw_params_t *params,
    695 			     snd_pcm_hw_param_t var,
    696 			     unsigned int *val, int *dir);
    697 int snd_pcm_hw_param_get_max(const snd_pcm_hw_params_t *params,
    698 			     snd_pcm_hw_param_t var,
    699 			     unsigned int *val, int *dir);
    700 
    701 #ifdef INTERNAL
    702 snd_pcm_sframes_t INTERNAL(snd_pcm_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
    703 
    704 int INTERNAL(snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access);
    705 int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access);
    706 int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access);
    707 int INTERNAL(snd_pcm_hw_params_set_access_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access);
    708 int INTERNAL(snd_pcm_hw_params_set_access_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access);
    709 int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
    710 int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
    711 
    712 int INTERNAL(snd_pcm_hw_params_get_format)(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val);
    713 int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
    714 int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
    715 int INTERNAL(snd_pcm_hw_params_set_format_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format);
    716 int INTERNAL(snd_pcm_hw_params_set_format_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format);
    717 int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
    718 void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
    719 
    720 int INTERNAL(snd_pcm_hw_params_get_subformat)(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
    721 int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat);
    722 int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat);
    723 int INTERNAL(snd_pcm_hw_params_set_subformat_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
    724 int INTERNAL(snd_pcm_hw_params_set_subformat_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
    725 int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
    726 void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
    727 
    728 int INTERNAL(snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *params, unsigned int *val);
    729 int INTERNAL(snd_pcm_hw_params_get_channels_min)(const snd_pcm_hw_params_t *params, unsigned int *val);
    730 int INTERNAL(snd_pcm_hw_params_get_channels_max)(const snd_pcm_hw_params_t *params, unsigned int *val);
    731 int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
    732 int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
    733 int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
    734 int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
    735 int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max);
    736 int INTERNAL(snd_pcm_hw_params_set_channels_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
    737 int INTERNAL(snd_pcm_hw_params_set_channels_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
    738 int INTERNAL(snd_pcm_hw_params_set_channels_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
    739 
    740 int INTERNAL(snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    741 int INTERNAL(snd_pcm_hw_params_get_rate_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    742 int INTERNAL(snd_pcm_hw_params_get_rate_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    743 int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    744 int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    745 int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    746 int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    747 int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
    748 int INTERNAL(snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    749 int INTERNAL(snd_pcm_hw_params_set_rate_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    750 int INTERNAL(snd_pcm_hw_params_set_rate_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    751 
    752 int INTERNAL(snd_pcm_hw_params_get_period_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    753 int INTERNAL(snd_pcm_hw_params_get_period_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    754 int INTERNAL(snd_pcm_hw_params_get_period_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    755 int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    756 int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    757 int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    758 int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    759 int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
    760 int INTERNAL(snd_pcm_hw_params_set_period_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    761 int INTERNAL(snd_pcm_hw_params_set_period_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    762 int INTERNAL(snd_pcm_hw_params_set_period_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    763 
    764 int INTERNAL(snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
    765 int INTERNAL(snd_pcm_hw_params_get_period_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
    766 int INTERNAL(snd_pcm_hw_params_get_period_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir);
    767 int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
    768 int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir);
    769 int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
    770 int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
    771 int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir);
    772 int INTERNAL(snd_pcm_hw_params_set_period_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
    773 int INTERNAL(snd_pcm_hw_params_set_period_size_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
    774 int INTERNAL(snd_pcm_hw_params_set_period_size_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
    775 int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    776 
    777 int INTERNAL(snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    778 int INTERNAL(snd_pcm_hw_params_get_periods_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    779 int INTERNAL(snd_pcm_hw_params_get_periods_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    780 int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    781 int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    782 int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    783 int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    784 int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
    785 int INTERNAL(snd_pcm_hw_params_set_periods_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    786 int INTERNAL(snd_pcm_hw_params_set_periods_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    787 int INTERNAL(snd_pcm_hw_params_set_periods_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    788 int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
    789 
    790 int INTERNAL(snd_pcm_hw_params_get_buffer_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    791 int INTERNAL(snd_pcm_hw_params_get_buffer_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    792 int INTERNAL(snd_pcm_hw_params_get_buffer_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    793 int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    794 int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
    795 int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    796 int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    797 int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
    798 int INTERNAL(snd_pcm_hw_params_set_buffer_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    799 int INTERNAL(snd_pcm_hw_params_set_buffer_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    800 int INTERNAL(snd_pcm_hw_params_set_buffer_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
    801 
    802 int INTERNAL(snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    803 int INTERNAL(snd_pcm_hw_params_get_buffer_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    804 int INTERNAL(snd_pcm_hw_params_get_buffer_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    805 int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
    806 int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
    807 int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    808 int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    809 int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max);
    810 int INTERNAL(snd_pcm_hw_params_set_buffer_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    811 int INTERNAL(snd_pcm_hw_params_set_buffer_size_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    812 int INTERNAL(snd_pcm_hw_params_set_buffer_size_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
    813 
    814 int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val);
    815 int INTERNAL(snd_pcm_sw_params_get_tstamp_mode)(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val);
    816 int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
    817 int INTERNAL(snd_pcm_sw_params_get_avail_min)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
    818 int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
    819 int INTERNAL(snd_pcm_sw_params_get_start_threshold)(const snd_pcm_sw_params_t *paramsm, snd_pcm_uframes_t *val);
    820 int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
    821 int INTERNAL(snd_pcm_sw_params_get_stop_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
    822 int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
    823 int INTERNAL(snd_pcm_sw_params_get_silence_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
    824 int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
    825 int INTERNAL(snd_pcm_sw_params_get_silence_size)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
    826 #endif /* INTERNAL */
    827 
    828 const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t param);
    829 void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params,
    830 			   snd_pcm_hw_param_t var, snd_output_t *out);
    831 #if 0
    832 int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy, int order,
    833 				    snd_pcm_hw_param_t var,
    834 				    unsigned int best,
    835 				    unsigned int mul);
    836 int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int order,
    837 				       snd_pcm_hw_param_t var,
    838 				       unsigned int count,
    839 				       snd_pcm_hw_strategy_simple_choices_list_t *choices);
    840 #endif
    841 
    842 #define SCONF_MANDATORY	1
    843 #define SCONF_UNCHANGED	2
    844 
    845 int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
    846 		       snd_config_t **pcm_conf, unsigned int count, ...);
    847 
    848 #define SND_PCM_APPEND	(1<<8)
    849 
    850 int snd_pcm_open_named_slave(snd_pcm_t **pcmp, const char *name,
    851 			     snd_config_t *root,
    852 			     snd_config_t *conf, snd_pcm_stream_t stream,
    853 			     int mode, snd_config_t *parent_conf);
    854 static inline int
    855 snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
    856 		   snd_config_t *conf, snd_pcm_stream_t stream,
    857 		   int mode, snd_config_t *parent_conf)
    858 {
    859 	return snd_pcm_open_named_slave(pcmp, NULL, root, conf, stream,
    860 					mode, parent_conf);
    861 }
    862 int snd_pcm_conf_generic_id(const char *id);
    863 
    864 int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd, int mmap_emulation, int sync_ptr_ioctl);
    865 int __snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
    866 			     snd_pcm_t *slave, int close_slave);
    867 
    868 int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout);
    869 
    870 const snd_config_t *snd_pcm_rate_get_default_converter(snd_config_t *root);
    871 
    872 #define SND_PCM_HW_PARBIT_ACCESS	(1U << SND_PCM_HW_PARAM_ACCESS)
    873 #define SND_PCM_HW_PARBIT_FORMAT	(1U << SND_PCM_HW_PARAM_FORMAT)
    874 #define SND_PCM_HW_PARBIT_SUBFORMAT	(1U << SND_PCM_HW_PARAM_SUBFORMAT)
    875 #define SND_PCM_HW_PARBIT_CHANNELS	(1U << SND_PCM_HW_PARAM_CHANNELS)
    876 #define SND_PCM_HW_PARBIT_RATE		(1U << SND_PCM_HW_PARAM_RATE)
    877 #define SND_PCM_HW_PARBIT_PERIOD_TIME	(1U << SND_PCM_HW_PARAM_PERIOD_TIME)
    878 #define SND_PCM_HW_PARBIT_PERIOD_SIZE	(1U << SND_PCM_HW_PARAM_PERIOD_SIZE)
    879 #define SND_PCM_HW_PARBIT_PERIODS	(1U << SND_PCM_HW_PARAM_PERIODS)
    880 #define SND_PCM_HW_PARBIT_BUFFER_TIME	(1U << SND_PCM_HW_PARAM_BUFFER_TIME)
    881 #define SND_PCM_HW_PARBIT_BUFFER_SIZE	(1U << SND_PCM_HW_PARAM_BUFFER_SIZE)
    882 #define SND_PCM_HW_PARBIT_SAMPLE_BITS	(1U << SND_PCM_HW_PARAM_SAMPLE_BITS)
    883 #define SND_PCM_HW_PARBIT_FRAME_BITS	(1U << SND_PCM_HW_PARAM_FRAME_BITS)
    884 #define SND_PCM_HW_PARBIT_PERIOD_BYTES	(1U << SND_PCM_HW_PARAM_PERIOD_BYTES)
    885 #define SND_PCM_HW_PARBIT_BUFFER_BYTES	(1U << SND_PCM_HW_PARAM_BUFFER_BYTES)
    886 #define SND_PCM_HW_PARBIT_TICK_TIME	(1U << SND_PCM_HW_PARAM_TICK_TIME)
    887 
    888 
    889 #define SND_PCM_ACCBIT_MMAP { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
    890 			     (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
    891 			     (1U << SND_PCM_ACCESS_MMAP_COMPLEX)) }
    892 #define SND_PCM_ACCBIT_MMAPI { (1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) }
    893 #define SND_PCM_ACCBIT_MMAPN { (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) }
    894 #define SND_PCM_ACCBIT_MMAPC { (1U << SND_PCM_ACCESS_MMAP_COMPLEX) }
    895 
    896 #define SND_PCM_ACCBIT_SHM { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
    897 			    (1U << SND_PCM_ACCESS_RW_INTERLEAVED) | \
    898 			    (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
    899 			    (1U << SND_PCM_ACCESS_RW_NONINTERLEAVED)) }
    900 #define SND_PCM_ACCBIT_SHMI { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
    901 			     (1U << SND_PCM_ACCESS_RW_INTERLEAVED)) }
    902 #define SND_PCM_ACCBIT_SHMN { ((1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
    903 			     (1U << SND_PCM_ACCESS_RW_NONINTERLEAVED)) }
    904 
    905 #define SND_PCM_FMTBIT_LINEAR \
    906 	{ ((1U << SND_PCM_FORMAT_S8) | \
    907 	 (1U << SND_PCM_FORMAT_U8) | \
    908 	 (1U << SND_PCM_FORMAT_S16_LE) | \
    909 	 (1U << SND_PCM_FORMAT_S16_BE) | \
    910 	 (1U << SND_PCM_FORMAT_U16_LE) | \
    911 	 (1U << SND_PCM_FORMAT_U16_BE) | \
    912 	 (1U << SND_PCM_FORMAT_S24_LE) | \
    913 	 (1U << SND_PCM_FORMAT_S24_BE) | \
    914 	 (1U << SND_PCM_FORMAT_U24_LE) | \
    915 	 (1U << SND_PCM_FORMAT_U24_BE) | \
    916 	 (1U << SND_PCM_FORMAT_S32_LE) | \
    917 	 (1U << SND_PCM_FORMAT_S32_BE) | \
    918 	 (1U << SND_PCM_FORMAT_U32_LE) | \
    919 	 (1U << SND_PCM_FORMAT_U32_BE)), \
    920 	((1U << (SND_PCM_FORMAT_S24_3LE - 32)) | \
    921 	 (1U << (SND_PCM_FORMAT_U24_3LE - 32)) | \
    922 	 (1U << (SND_PCM_FORMAT_S24_3BE - 32)) | \
    923 	 (1U << (SND_PCM_FORMAT_U24_3BE - 32)) | \
    924 	 (1U << (SND_PCM_FORMAT_S20_3LE - 32)) | \
    925 	 (1U << (SND_PCM_FORMAT_U20_3LE - 32)) | \
    926 	 (1U << (SND_PCM_FORMAT_S20_3BE - 32)) | \
    927 	 (1U << (SND_PCM_FORMAT_U20_3BE - 32)) | \
    928 	 (1U << (SND_PCM_FORMAT_S18_3LE - 32)) | \
    929 	 (1U << (SND_PCM_FORMAT_U18_3LE - 32)) | \
    930 	 (1U << (SND_PCM_FORMAT_S18_3BE - 32)) | \
    931 	 (1U << (SND_PCM_FORMAT_U18_3BE - 32))) }
    932 
    933 
    934 #define SND_PCM_FMTBIT_FLOAT \
    935 	{ ((1U << SND_PCM_FORMAT_FLOAT_LE) | \
    936 	 (1U << SND_PCM_FORMAT_FLOAT_BE) | \
    937 	 (1U << SND_PCM_FORMAT_FLOAT64_LE) | \
    938 	 (1U << SND_PCM_FORMAT_FLOAT64_BE)) }
    939 
    940 
    941 typedef union snd_tmp_float {
    942 	float f;
    943 	int32_t i;
    944 } snd_tmp_float_t;
    945 
    946 typedef union snd_tmp_double {
    947 	double d;
    948 	int64_t l;
    949 } snd_tmp_double_t;
    950 
    951 /* get the current timestamp */
    952 static inline void gettimestamp(snd_htimestamp_t *tstamp, int monotonic)
    953 {
    954 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
    955 	if (monotonic) {
    956 		clock_gettime(CLOCK_MONOTONIC, tstamp);
    957 	} else {
    958 #endif
    959 		struct timeval tv;
    960 
    961 		gettimeofday(&tv, 0);
    962 		tstamp->tv_sec = tv.tv_sec;
    963 		tstamp->tv_nsec = tv.tv_usec * 1000L;
    964 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
    965 	}
    966 #endif
    967 }
    968