1/* 2 * PCM Interface - local header file 3 * Copyright (c) 2000 by Jaroslav Kysela <perex@perex.cz> 4 * Abramo Bagnara <abramo@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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * 21 */ 22 23#ifndef __PCM_LOCAL_H 24#define __PCM_LOCAL_H 25 26#include "config.h" 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <limits.h> 31#include <sys/uio.h> 32#include <time.h> 33#include <sys/time.h> 34 35#define _snd_mask sndrv_mask 36#define _snd_pcm_access_mask _snd_mask 37#define _snd_pcm_format_mask _snd_mask 38#define _snd_pcm_subformat_mask _snd_mask 39 40#include "local.h" 41 42#ifdef THREAD_SAFE_API 43#define __USE_UNIX98 1 /* for old glibc */ 44#include <pthread.h> 45#endif 46 47#define SND_INTERVAL_INLINE 48#include "interval.h" 49 50#define SND_MASK_INLINE 51#include "mask.h" 52 53#define SND_PCM_HW_PARAM_ACCESS SNDRV_PCM_HW_PARAM_ACCESS 54#define SND_PCM_HW_PARAM_FORMAT SNDRV_PCM_HW_PARAM_FORMAT 55#define SND_PCM_HW_PARAM_SUBFORMAT SNDRV_PCM_HW_PARAM_SUBFORMAT 56#define SND_PCM_HW_PARAM_SAMPLE_BITS SNDRV_PCM_HW_PARAM_SAMPLE_BITS 57#define SND_PCM_HW_PARAM_FRAME_BITS SNDRV_PCM_HW_PARAM_FRAME_BITS 58#define SND_PCM_HW_PARAM_CHANNELS SNDRV_PCM_HW_PARAM_CHANNELS 59#define SND_PCM_HW_PARAM_RATE SNDRV_PCM_HW_PARAM_RATE 60#define SND_PCM_HW_PARAM_PERIOD_TIME SNDRV_PCM_HW_PARAM_PERIOD_TIME 61#define SND_PCM_HW_PARAM_PERIOD_SIZE SNDRV_PCM_HW_PARAM_PERIOD_SIZE 62#define SND_PCM_HW_PARAM_PERIOD_BYTES SNDRV_PCM_HW_PARAM_PERIOD_BYTES 63#define SND_PCM_HW_PARAM_PERIODS SNDRV_PCM_HW_PARAM_PERIODS 64#define SND_PCM_HW_PARAM_BUFFER_TIME SNDRV_PCM_HW_PARAM_BUFFER_TIME 65#define SND_PCM_HW_PARAM_BUFFER_SIZE SNDRV_PCM_HW_PARAM_BUFFER_SIZE 66#define SND_PCM_HW_PARAM_BUFFER_BYTES SNDRV_PCM_HW_PARAM_BUFFER_BYTES 67#define SND_PCM_HW_PARAM_TICK_TIME SNDRV_PCM_HW_PARAM_TICK_TIME 68#define SND_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_LAST_MASK 69#define SND_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_FIRST_MASK 70#define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL 71#define SND_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_FIRST_INTERVAL 72 73/** device accepts mmaped access */ 74#define SND_PCM_INFO_MMAP SNDRV_PCM_INFO_MMAP 75/** device accepts mmaped access with sample resolution */ 76#define SND_PCM_INFO_MMAP_VALID SNDRV_PCM_INFO_MMAP_VALID 77/** device is doing double buffering */ 78#define SND_PCM_INFO_DOUBLE SNDRV_PCM_INFO_DOUBLE 79/** device transfers samples in batch */ 80#define SND_PCM_INFO_BATCH SNDRV_PCM_INFO_BATCH 81/** device does perfect drain (silencing not required) */ 82#define SND_PCM_INFO_PERFECT_DRAIN SNDRV_PCM_INFO_PERFECT_DRAIN 83/** device accepts interleaved samples */ 84#define SND_PCM_INFO_INTERLEAVED SNDRV_PCM_INFO_INTERLEAVED 85/** device accepts non-interleaved samples */ 86#define SND_PCM_INFO_NONINTERLEAVED SNDRV_PCM_INFO_NONINTERLEAVED 87/** device accepts complex sample organization */ 88#define SND_PCM_INFO_COMPLEX SNDRV_PCM_INFO_COMPLEX 89/** device is capable block transfers */ 90#define SND_PCM_INFO_BLOCK_TRANSFER SNDRV_PCM_INFO_BLOCK_TRANSFER 91/** device can detect DAC/ADC overrange */ 92#define SND_PCM_INFO_OVERRANGE SNDRV_PCM_INFO_OVERRANGE 93/** device supports resume */ 94#define SND_PCM_INFO_RESUME SNDRV_PCM_INFO_RESUME 95/** device is capable to pause */ 96#define SND_PCM_INFO_PAUSE SNDRV_PCM_INFO_PAUSE 97/** device can do only half duplex */ 98#define SND_PCM_INFO_HALF_DUPLEX SNDRV_PCM_INFO_HALF_DUPLEX 99/** device can do only joint duplex (same parameters) */ 100#define SND_PCM_INFO_JOINT_DUPLEX SNDRV_PCM_INFO_JOINT_DUPLEX 101/** device can do a kind of synchronized start */ 102#define SND_PCM_INFO_SYNC_START SNDRV_PCM_INFO_SYNC_START 103/** device can disable period wakeups */ 104#define SND_PCM_INFO_NO_PERIOD_WAKEUP SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 105 106#define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE 107#define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER 108#define SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP 109#define SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE 110 111#define SND_PCM_INFO_MONOTONIC 0x80000000 112 113typedef struct _snd_pcm_rbptr { 114 snd_pcm_t *master; 115 volatile snd_pcm_uframes_t *ptr; 116 int fd; 117 off_t offset; 118 int link_dst_count; 119 snd_pcm_t **link_dst; 120 void *private_data; 121 void (*changed)(snd_pcm_t *pcm, snd_pcm_t *src); 122} snd_pcm_rbptr_t; 123 124typedef struct _snd_pcm_channel_info { 125 unsigned int channel; 126 void *addr; /* base address of channel samples */ 127 unsigned int first; /* offset to first sample in bits */ 128 unsigned int step; /* samples distance in bits */ 129 enum { SND_PCM_AREA_SHM, SND_PCM_AREA_MMAP, SND_PCM_AREA_LOCAL } type; 130 union { 131 struct { 132 struct snd_shm_area *area; 133 int shmid; 134 } shm; 135 struct { 136 int fd; 137 off_t offset; 138 } mmap; 139 } u; 140 char reserved[64]; 141} snd_pcm_channel_info_t; 142 143typedef struct { 144 int (*close)(snd_pcm_t *pcm); 145 int (*nonblock)(snd_pcm_t *pcm, int nonblock); /* always locked */ 146 int (*async)(snd_pcm_t *pcm, int sig, pid_t pid); 147 int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info); 148 int (*hw_refine)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 149 int (*hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 150 int (*hw_free)(snd_pcm_t *pcm); 151 int (*sw_params)(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); /* always locked */ 152 int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info); 153 void (*dump)(snd_pcm_t *pcm, snd_output_t *out); 154 int (*mmap)(snd_pcm_t *pcm); 155 int (*munmap)(snd_pcm_t *pcm); 156 snd_pcm_chmap_query_t **(*query_chmaps)(snd_pcm_t *pcm); 157 snd_pcm_chmap_t *(*get_chmap)(snd_pcm_t *pcm); 158 int (*set_chmap)(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); 159} snd_pcm_ops_t; 160 161typedef struct { 162 int (*status)(snd_pcm_t *pcm, snd_pcm_status_t *status); /* locked */ 163 int (*prepare)(snd_pcm_t *pcm); /* locked */ 164 int (*reset)(snd_pcm_t *pcm); /* locked */ 165 int (*start)(snd_pcm_t *pcm); /* locked */ 166 int (*drop)(snd_pcm_t *pcm); /* locked */ 167 int (*drain)(snd_pcm_t *pcm); /* need own locking */ 168 int (*pause)(snd_pcm_t *pcm, int enable); /* locked */ 169 snd_pcm_state_t (*state)(snd_pcm_t *pcm); /* locked */ 170 int (*hwsync)(snd_pcm_t *pcm); /* locked */ 171 int (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp); /* locked */ 172 int (*resume)(snd_pcm_t *pcm); /* need own locking */ 173 int (*link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2); 174 int (*link_slaves)(snd_pcm_t *pcm, snd_pcm_t *master); 175 int (*unlink)(snd_pcm_t *pcm); 176 snd_pcm_sframes_t (*rewindable)(snd_pcm_t *pcm); /* locked */ 177 snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames); /* locked */ 178 snd_pcm_sframes_t (*forwardable)(snd_pcm_t *pcm); /* locked */ 179 snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames); /* locked */ 180 snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); /* need own locking */ 181 snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); /* need own locking */ 182 snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); /* need own locking */ 183 snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); /* need own locking */ 184 snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm); /* locked */ 185 snd_pcm_sframes_t (*mmap_commit)(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t size); /* locked */ 186 int (*htimestamp)(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp); /* locked */ 187 int (*poll_descriptors_count)(snd_pcm_t *pcm); /* locked */ 188 int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); /* locked */ 189 int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); /* locked */ 190 int (*may_wait_for_avail_min)(snd_pcm_t *pcm, snd_pcm_uframes_t avail); 191 int (*mmap_begin)(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); /* locked */ 192} snd_pcm_fast_ops_t; 193 194struct _snd_pcm { 195 void *open_func; 196 char *name; 197 snd_pcm_type_t type; 198 snd_pcm_stream_t stream; 199 int mode; 200 long minperiodtime; /* in us */ 201 int poll_fd_count; 202 int poll_fd; 203 unsigned short poll_events; 204 int setup: 1, 205 compat: 1; 206 snd_pcm_access_t access; /* access mode */ 207 snd_pcm_format_t format; /* SND_PCM_FORMAT_* */ 208 snd_pcm_subformat_t subformat; /* subformat */ 209 unsigned int channels; /* channels */ 210 unsigned int rate; /* rate in Hz */ 211 snd_pcm_uframes_t period_size; 212 unsigned int period_time; /* period duration */ 213 snd_interval_t periods; 214 snd_pcm_tstamp_t tstamp_mode; /* timestamp mode */ 215 snd_pcm_tstamp_type_t tstamp_type; /* timestamp type */ 216 unsigned int period_step; 217 snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */ 218 int period_event; 219 snd_pcm_uframes_t start_threshold; 220 snd_pcm_uframes_t stop_threshold; 221 snd_pcm_uframes_t silence_threshold; /* Silence filling happens when 222 noise is nearest than this */ 223 snd_pcm_uframes_t silence_size; /* Silence filling size */ 224 snd_pcm_uframes_t boundary; /* pointers wrap point */ 225 unsigned int info; /* Info for returned setup */ 226 unsigned int msbits; /* used most significant bits */ 227 unsigned int rate_num; /* rate numerator */ 228 unsigned int rate_den; /* rate denominator */ 229 unsigned int hw_flags; /* actual hardware flags */ 230 snd_pcm_uframes_t fifo_size; /* chip FIFO size in frames */ 231 snd_pcm_uframes_t buffer_size; 232 snd_interval_t buffer_time; 233 unsigned int sample_bits; 234 unsigned int frame_bits; 235 snd_pcm_rbptr_t appl; 236 snd_pcm_rbptr_t hw; 237 snd_pcm_uframes_t min_align; 238 unsigned int mmap_rw: 1; /* use always mmapped buffer */ 239 unsigned int mmap_shadow: 1; /* don't call actual mmap, 240 * use the mmaped buffer of the slave 241 */ 242 unsigned int donot_close: 1; /* don't close this PCM */ 243 unsigned int own_state_check:1; /* plugin has own PCM state check */ 244 snd_pcm_channel_info_t *mmap_channels; 245 snd_pcm_channel_area_t *running_areas; 246 snd_pcm_channel_area_t *stopped_areas; 247 const snd_pcm_ops_t *ops; 248 const snd_pcm_fast_ops_t *fast_ops; 249 snd_pcm_t *op_arg; 250 snd_pcm_t *fast_op_arg; 251 void *private_data; 252 struct list_head async_handlers; 253#ifdef THREAD_SAFE_API 254 int need_lock; /* true = this PCM (plugin) is thread-unsafe, 255 * thus it needs a lock. 256 */ 257 int lock_enabled; /* thread-safety lock is enabled on the system; 258 * it's set depending on $LIBASOUND_THREAD_SAFE. 259 */ 260 pthread_mutex_t lock; 261#endif 262}; 263 264/* make local functions really local */ 265/* Grrr, these cannot be local - a bad aserver uses them! 266#define snd_pcm_async \ 267 snd1_pcm_async 268#define snd_pcm_mmap \ 269 snd1_pcm_mmap 270#define snd_pcm_munmap \ 271 snd1_pcm_munmap 272#define snd_pcm_hw_refine \ 273 snd1_pcm_hw_refine 274*/ 275#define snd_pcm_new \ 276 snd1_pcm_new 277#define snd_pcm_free \ 278 snd1_pcm_free 279#define snd_pcm_areas_from_buf \ 280 snd1_pcm_areas_from_buf 281#define snd_pcm_areas_from_bufs \ 282 snd1_pcm_areas_from_bufs 283#define snd_pcm_open_named_slave \ 284 snd1_pcm_open_named_slave 285#define snd_pcm_hw_open_fd \ 286 snd1_pcm_hw_open_fd 287#define snd_pcm_wait_nocheck \ 288 snd1_pcm_wait_nocheck 289#define snd_pcm_rate_get_default_converter \ 290 snd1_pcm_rate_get_default_converter 291#define snd_pcm_set_hw_ptr \ 292 snd1_pcm_set_hw_ptr 293#define snd_pcm_set_appl_ptr \ 294 snd1_pcm_set_appl_ptr 295#define snd_pcm_link_hw_ptr \ 296 snd1_pcm_link_hw_ptr 297#define snd_pcm_link_appl_ptr \ 298 snd1_pcm_link_appl_ptr 299#define snd_pcm_unlink_hw_ptr \ 300 snd1_pcm_unlink_hw_ptr 301#define snd_pcm_unlink_appl_ptr \ 302 snd1_pcm_unlink_appl_ptr 303#define snd_pcm_mmap_appl_ptr \ 304 snd1_pcm_mmap_appl_ptr 305#define snd_pcm_mmap_appl_backward \ 306 snd1_pcm_mmap_appl_backward 307#define snd_pcm_mmap_appl_forward \ 308 snd1_pcm_mmap_appl_forward 309#define snd_pcm_mmap_hw_backward \ 310 snd1_pcm_mmap_hw_backward 311#define snd_pcm_mmap_hw_forward \ 312 snd1_pcm_mmap_hw_forward 313#define snd_pcm_read_areas \ 314 snd1_pcm_read_areas 315#define snd_pcm_write_areas \ 316 snd1_pcm_write_areas 317#define snd_pcm_read_mmap \ 318 snd1_pcm_read_mmap 319#define snd_pcm_write_mmap \ 320 snd1_pcm_write_mmap 321#define snd_pcm_channel_info_shm \ 322 snd1_pcm_channel_info_shm 323#define snd_pcm_hw_refine_soft \ 324 snd1_pcm_hw_refine_soft 325#define snd_pcm_hw_refine_slave \ 326 snd1_pcm_hw_refine_slave 327#define snd_pcm_hw_params_slave \ 328 snd1_pcm_hw_params_slave 329#define snd_pcm_hw_param_refine_near \ 330 snd1_pcm_hw_param_refine_near 331#define snd_pcm_hw_param_refine_multiple \ 332 snd1_pcm_hw_param_refine_multiple 333#define snd_pcm_hw_param_empty \ 334 snd1_pcm_hw_param_empty 335#define snd_pcm_hw_param_always_eq \ 336 snd1_pcm_hw_param_always_eq 337#define snd_pcm_hw_param_never_eq \ 338 snd1_pcm_hw_param_never_eq 339#define snd_pcm_hw_param_get_mask \ 340 snd1_pcm_hw_param_get_mask 341#define snd_pcm_hw_param_get_interval \ 342 snd1_pcm_hw_param_get_interval 343#define snd_pcm_hw_param_any \ 344 snd1_pcm_hw_param_any 345#define snd_pcm_hw_param_set_integer \ 346 snd1_pcm_hw_param_set_integer 347#define snd_pcm_hw_param_set_first \ 348 snd1_pcm_hw_param_set_first 349#define snd_pcm_hw_param_set_last \ 350 snd1_pcm_hw_param_set_last 351#define snd_pcm_hw_param_set_near \ 352 snd1_pcm_hw_param_set_near 353#define snd_pcm_hw_param_set_min \ 354 snd1_pcm_hw_param_set_min 355#define snd_pcm_hw_param_set_max \ 356 snd1_pcm_hw_param_set_max 357#define snd_pcm_hw_param_set_minmax \ 358 snd1_pcm_hw_param_set_minmax 359#define snd_pcm_hw_param_set \ 360 snd1_pcm_hw_param_set 361#define snd_pcm_hw_param_set_mask \ 362 snd1_pcm_hw_param_set_mask 363#define snd_pcm_hw_param_get \ 364 snd1_pcm_hw_param_get 365#define snd_pcm_hw_param_get_min \ 366 snd1_pcm_hw_param_get_min 367#define snd_pcm_hw_param_get_max \ 368 snd1_pcm_hw_param_get_max 369#define snd_pcm_hw_param_name \ 370 snd1_pcm_hw_param_name 371#define snd_pcm_sw_params_current_no_lock \ 372 snd1_pcm_sw_params_current_no_lock 373 374int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name, 375 snd_pcm_stream_t stream, int mode); 376int snd_pcm_free(snd_pcm_t *pcm); 377 378void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf); 379void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs); 380 381int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid); 382int snd_pcm_mmap(snd_pcm_t *pcm); 383int snd_pcm_munmap(snd_pcm_t *pcm); 384int snd_pcm_mmap_ready(snd_pcm_t *pcm); 385void snd_pcm_set_hw_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset); 386void snd_pcm_set_appl_ptr(snd_pcm_t *pcm, volatile snd_pcm_uframes_t *appl_ptr, int fd, off_t offset); 387void snd_pcm_link_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave); 388void snd_pcm_link_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave); 389void snd_pcm_unlink_hw_ptr(snd_pcm_t *pcm, snd_pcm_t *slave); 390void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave); 391snd_pcm_sframes_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset); 392void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); 393void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); 394void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); 395void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); 396 397void snd_pcm_sw_params_current_no_lock(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); 398 399snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); 400snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); 401snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); 402snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); 403 404typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm, 405 const snd_pcm_channel_area_t *areas, 406 snd_pcm_uframes_t offset, 407 snd_pcm_uframes_t size); 408 409snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, 410 snd_pcm_uframes_t offset, snd_pcm_uframes_t size, 411 snd_pcm_xfer_areas_func_t func); 412snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, 413 snd_pcm_uframes_t offset, snd_pcm_uframes_t size, 414 snd_pcm_xfer_areas_func_t func); 415snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset, 416 snd_pcm_uframes_t size); 417snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset, 418 snd_pcm_uframes_t size); 419static inline int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info) 420{ 421 if (!pcm->ops->channel_info) 422 return -ENOSYS; 423 return pcm->ops->channel_info(pcm, info); 424} 425int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid); 426int _snd_pcm_poll_descriptor(snd_pcm_t *pcm); 427#define _snd_pcm_link_descriptor _snd_pcm_poll_descriptor /* FIXME */ 428#define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor /* FIXME */ 429 430/* locked versions */ 431int __snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, 432 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); 433int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, 434 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); 435snd_pcm_sframes_t __snd_pcm_mmap_commit(snd_pcm_t *pcm, 436 snd_pcm_uframes_t offset, 437 snd_pcm_uframes_t frames); 438int __snd_pcm_wait_in_lock(snd_pcm_t *pcm, int timeout); 439 440static inline snd_pcm_sframes_t __snd_pcm_avail_update(snd_pcm_t *pcm) 441{ 442 if (!pcm->fast_ops->avail_update) 443 return -ENOSYS; 444 return pcm->fast_ops->avail_update(pcm->fast_op_arg); 445} 446 447static inline int __snd_pcm_start(snd_pcm_t *pcm) 448{ 449 if (!pcm->fast_ops->start) 450 return -ENOSYS; 451 return pcm->fast_ops->start(pcm->fast_op_arg); 452} 453 454static inline snd_pcm_state_t __snd_pcm_state(snd_pcm_t *pcm) 455{ 456 if (!pcm->fast_ops->state) 457 return SND_PCM_STATE_OPEN; 458 return pcm->fast_ops->state(pcm->fast_op_arg); 459} 460 461static inline int __snd_pcm_hwsync(snd_pcm_t *pcm) 462{ 463 if (!pcm->fast_ops->hwsync) 464 return -ENOSYS; 465 return pcm->fast_ops->hwsync(pcm->fast_op_arg); 466} 467 468static inline int __snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) 469{ 470 if (!pcm->fast_ops->delay) 471 return -ENOSYS; 472 return pcm->fast_ops->delay(pcm->fast_op_arg, delayp); 473} 474 475/* handle special error cases */ 476static inline int snd_pcm_check_error(snd_pcm_t *pcm, int err) 477{ 478 if (err == -EINTR) { 479 switch (__snd_pcm_state(pcm)) { 480 case SND_PCM_STATE_XRUN: 481 return -EPIPE; 482 case SND_PCM_STATE_SUSPENDED: 483 return -ESTRPIPE; 484 case SND_PCM_STATE_DISCONNECTED: 485 return -ENODEV; 486 default: 487 break; 488 } 489 } 490 return err; 491} 492 493/** 494 * \retval number of frames available to the application for playback 495 * 496 * This is how far ahead the hardware position in the ring buffer is, 497 * compared to the application position. ie. for playback it's the 498 * number of frames in the empty part of the ring buffer. 499 */ 500static inline snd_pcm_uframes_t __snd_pcm_playback_avail(snd_pcm_t *pcm, 501 const snd_pcm_uframes_t hw_ptr, 502 const snd_pcm_uframes_t appl_ptr) 503{ 504 snd_pcm_sframes_t avail; 505 avail = hw_ptr + pcm->buffer_size - appl_ptr; 506 if (avail < 0) 507 avail += pcm->boundary; 508 else if ((snd_pcm_uframes_t) avail >= pcm->boundary) 509 avail -= pcm->boundary; 510 return avail; 511} 512 513static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm) 514{ 515 return __snd_pcm_playback_avail(pcm, *pcm->hw.ptr, *pcm->appl.ptr); 516} 517 518/* 519 * \retval number of frames available to the application for capture 520 * 521 * This is how far ahead the hardware position in the ring buffer is 522 * compared to the application position. ie. for capture, it's the 523 * number of frames in the filled part of the ring buffer. 524 */ 525static inline snd_pcm_uframes_t __snd_pcm_capture_avail(snd_pcm_t *pcm, 526 const snd_pcm_uframes_t hw_ptr, 527 const snd_pcm_uframes_t appl_ptr) 528{ 529 snd_pcm_sframes_t avail; 530 avail = hw_ptr - appl_ptr; 531 if (avail < 0) 532 avail += pcm->boundary; 533 return avail; 534} 535 536static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm) 537{ 538 return __snd_pcm_capture_avail(pcm, *pcm->hw.ptr, *pcm->appl.ptr); 539} 540 541static inline snd_pcm_uframes_t __snd_pcm_avail(snd_pcm_t *pcm, 542 const snd_pcm_uframes_t hw_ptr, 543 const snd_pcm_uframes_t appl_ptr) 544{ 545 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) 546 return __snd_pcm_playback_avail(pcm, hw_ptr, appl_ptr); 547 else 548 return __snd_pcm_capture_avail(pcm, hw_ptr, appl_ptr); 549} 550 551static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm) 552{ 553 return __snd_pcm_avail(pcm, *pcm->hw.ptr, *pcm->appl.ptr); 554} 555 556/* 557 * \retval number of frames available to the hardware for playback 558 * 559 * ie. the filled part of the ring buffer 560 */ 561static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm) 562{ 563 return pcm->buffer_size - snd_pcm_mmap_playback_avail(pcm); 564} 565 566/* 567 * \retval number of frames available to the hardware for capture 568 * 569 * ie. the empty part of the ring buffer. 570 */ 571static inline snd_pcm_sframes_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm) 572{ 573 return pcm->buffer_size - snd_pcm_mmap_capture_avail(pcm); 574} 575 576static inline snd_pcm_sframes_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm) 577{ 578 return pcm->buffer_size - snd_pcm_mmap_avail(pcm); 579} 580 581static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_rewindable(snd_pcm_t *pcm) 582{ 583 snd_pcm_sframes_t ret = snd_pcm_mmap_playback_hw_avail(pcm); 584 return (ret >= 0) ? ret : 0; 585} 586 587static inline snd_pcm_sframes_t snd_pcm_mmap_capture_hw_rewindable(snd_pcm_t *pcm) 588{ 589 snd_pcm_sframes_t ret = snd_pcm_mmap_capture_hw_avail(pcm); 590 return (ret >= 0) ? ret : 0; 591} 592 593static inline snd_pcm_uframes_t snd_pcm_mmap_hw_rewindable(snd_pcm_t *pcm) 594{ 595 snd_pcm_sframes_t ret = snd_pcm_mmap_hw_avail(pcm); 596 return (ret >= 0) ? ret : 0; 597} 598 599static inline const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm) 600{ 601 if (pcm->stopped_areas && 602 __snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING) 603 return pcm->stopped_areas; 604 return pcm->running_areas; 605} 606 607static inline snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm) 608{ 609 assert(pcm); 610 return *pcm->appl.ptr % pcm->buffer_size; 611} 612 613static inline snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm) 614{ 615 assert(pcm); 616 return *pcm->hw.ptr % pcm->buffer_size; 617} 618 619/* 620 * \retval number of frames pending from application to hardware 621 */ 622static inline snd_pcm_uframes_t snd_pcm_mmap_playback_delay(snd_pcm_t *pcm) 623{ 624 return snd_pcm_mmap_playback_hw_avail(pcm); 625} 626 627/* 628 * \retval number of frames pending from hardware to application 629 */ 630static inline snd_pcm_uframes_t snd_pcm_mmap_capture_delay(snd_pcm_t *pcm) 631{ 632 return snd_pcm_mmap_capture_avail(pcm); 633} 634 635static inline snd_pcm_sframes_t snd_pcm_mmap_delay(snd_pcm_t *pcm) 636{ 637 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) 638 return snd_pcm_mmap_playback_delay(pcm); 639 else 640 return snd_pcm_mmap_capture_delay(pcm); 641} 642 643static inline snd_pcm_sframes_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size) 644{ 645 /* lock handled in the callback */ 646 if (!pcm->fast_ops->writei) 647 return -ENOSYS; 648 return pcm->fast_ops->writei(pcm->fast_op_arg, buffer, size); 649} 650 651static inline snd_pcm_sframes_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size) 652{ 653 /* lock handled in the callback */ 654 if (!pcm->fast_ops->writen) 655 return -ENOSYS; 656 return pcm->fast_ops->writen(pcm->fast_op_arg, bufs, size); 657} 658 659static inline snd_pcm_sframes_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size) 660{ 661 /* lock handled in the callback */ 662 if (!pcm->fast_ops->readi) 663 return -ENOSYS; 664 return pcm->fast_ops->readi(pcm->fast_op_arg, buffer, size); 665} 666 667static inline snd_pcm_sframes_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size) 668{ 669 /* lock handled in the callback */ 670 if (!pcm->fast_ops->readn) 671 return -ENOSYS; 672 return pcm->fast_ops->readn(pcm->fast_op_arg, bufs, size); 673} 674 675static inline int muldiv(int a, int b, int c, int *r) 676{ 677 int64_t n = (int64_t)a * b; 678 int64_t v = n / c; 679 if (v > INT_MAX) { 680 *r = 0; 681 return INT_MAX; 682 } 683 if (v < INT_MIN) { 684 *r = 0; 685 return INT_MIN; 686 } 687 *r = n % c; 688 return v; 689} 690 691static inline int muldiv_down(int a, int b, int c) 692{ 693 int64_t v = (int64_t)a * b / c; 694 if (v > INT_MAX) { 695 return INT_MAX; 696 } 697 if (v < INT_MIN) { 698 return INT_MIN; 699 } 700 return v; 701} 702 703static inline int muldiv_near(int a, int b, int c) 704{ 705 int r; 706 int n = muldiv(a, b, c, &r); 707 if (r >= (c + 1) / 2) 708 n++; 709 return n; 710} 711 712int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 713int _snd_pcm_hw_params_internal(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 714#undef _snd_pcm_hw_params 715int snd_pcm_hw_refine_soft(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 716int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 717 int (*cprepare)(snd_pcm_t *pcm, 718 snd_pcm_hw_params_t *params), 719 int (*cchange)(snd_pcm_t *pcm, 720 snd_pcm_hw_params_t *params, 721 snd_pcm_hw_params_t *sparams), 722 int (*sprepare)(snd_pcm_t *pcm, 723 snd_pcm_hw_params_t *params), 724 int (*schange)(snd_pcm_t *pcm, 725 snd_pcm_hw_params_t *params, 726 snd_pcm_hw_params_t *sparams), 727 int (*srefine)(snd_pcm_t *pcm, 728 snd_pcm_hw_params_t *sparams)); 729int snd_pcm_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 730 int (*cchange)(snd_pcm_t *pcm, 731 snd_pcm_hw_params_t *params, 732 snd_pcm_hw_params_t *sparams), 733 int (*sprepare)(snd_pcm_t *pcm, 734 snd_pcm_hw_params_t *params), 735 int (*schange)(snd_pcm_t *pcm, 736 snd_pcm_hw_params_t *params, 737 snd_pcm_hw_params_t *sparams), 738 int (*sparams)(snd_pcm_t *pcm, 739 snd_pcm_hw_params_t *sparams)); 740 741 742void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params); 743void _snd_pcm_hw_param_set_empty(snd_pcm_hw_params_t *params, 744 snd_pcm_hw_param_t var); 745int _snd_pcm_hw_param_set_interval(snd_pcm_hw_params_t *params, 746 snd_pcm_hw_param_t var, 747 const snd_interval_t *val); 748int _snd_pcm_hw_param_set_mask(snd_pcm_hw_params_t *params, 749 snd_pcm_hw_param_t var, const snd_mask_t *mask); 750int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, 751 snd_pcm_hw_param_t var); 752int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, 753 snd_pcm_hw_param_t var); 754int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, 755 snd_pcm_hw_param_t var, unsigned int val, int dir); 756static inline int _snd_pcm_hw_params_set_format(snd_pcm_hw_params_t *params, 757 snd_pcm_format_t val) 758{ 759 return _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_FORMAT, 760 (unsigned long) val, 0); 761} 762 763static inline int _snd_pcm_hw_params_set_subformat(snd_pcm_hw_params_t *params, 764 snd_pcm_subformat_t val) 765{ 766 return _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT, 767 (unsigned long) val, 0); 768} 769 770int _snd_pcm_hw_param_set_min(snd_pcm_hw_params_t *params, 771 snd_pcm_hw_param_t var, unsigned int val, int dir); 772int _snd_pcm_hw_param_set_max(snd_pcm_hw_params_t *params, 773 snd_pcm_hw_param_t var, unsigned int val, int dir); 774int _snd_pcm_hw_param_set_minmax(snd_pcm_hw_params_t *params, 775 snd_pcm_hw_param_t var, 776 unsigned int min, int mindir, 777 unsigned int max, int maxdir); 778int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params, 779 snd_pcm_hw_param_t var, 780 const snd_pcm_hw_params_t *src); 781int _snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params, 782 unsigned int vars, 783 const snd_pcm_hw_params_t *src); 784int snd_pcm_hw_param_refine_near(snd_pcm_t *pcm, 785 snd_pcm_hw_params_t *params, 786 snd_pcm_hw_param_t var, 787 const snd_pcm_hw_params_t *src); 788int snd_pcm_hw_param_refine_multiple(snd_pcm_t *pcm, 789 snd_pcm_hw_params_t *params, 790 snd_pcm_hw_param_t var, 791 const snd_pcm_hw_params_t *src); 792int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params, 793 snd_pcm_hw_param_t var); 794int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params, 795 snd_pcm_hw_param_t var, 796 const snd_pcm_hw_params_t *params1); 797int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params, 798 snd_pcm_hw_param_t var, 799 const snd_pcm_hw_params_t *params1); 800const snd_mask_t *snd_pcm_hw_param_get_mask(const snd_pcm_hw_params_t *params, 801 snd_pcm_hw_param_t var); 802const snd_interval_t *snd_pcm_hw_param_get_interval(const snd_pcm_hw_params_t *params, 803 snd_pcm_hw_param_t var); 804 805int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 806 snd_pcm_hw_param_t var); 807int snd_pcm_hw_param_set_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 808 snd_set_mode_t mode, 809 snd_pcm_hw_param_t var); 810int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 811 snd_pcm_hw_param_t var, unsigned int *rval, int *dir); 812int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 813 snd_pcm_hw_param_t var, unsigned int *rval, int *dir); 814int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 815 snd_pcm_hw_param_t var, unsigned int *val, int *dir); 816int snd_pcm_hw_param_set_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 817 snd_set_mode_t mode, 818 snd_pcm_hw_param_t var, 819 unsigned int *val, int *dir); 820int snd_pcm_hw_param_set_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 821 snd_set_mode_t mode, 822 snd_pcm_hw_param_t var, unsigned int *val, int *dir); 823int snd_pcm_hw_param_set_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 824 snd_set_mode_t mode, 825 snd_pcm_hw_param_t var, 826 unsigned int *min, int *mindir, 827 unsigned int *max, int *maxdir); 828int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 829 snd_set_mode_t mode, 830 snd_pcm_hw_param_t var, unsigned int val, int dir); 831int snd_pcm_hw_param_set_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 832 snd_set_mode_t mode, 833 snd_pcm_hw_param_t var, const snd_mask_t *mask); 834int snd_pcm_hw_param_get(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, 835 unsigned int *val, int *dir); 836int snd_pcm_hw_param_get_min(const snd_pcm_hw_params_t *params, 837 snd_pcm_hw_param_t var, 838 unsigned int *val, int *dir); 839int snd_pcm_hw_param_get_max(const snd_pcm_hw_params_t *params, 840 snd_pcm_hw_param_t var, 841 unsigned int *val, int *dir); 842 843#ifdef INTERNAL 844snd_pcm_sframes_t INTERNAL(snd_pcm_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames); 845 846int INTERNAL(snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access); 847int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access); 848int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access); 849int INTERNAL(snd_pcm_hw_params_set_access_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access); 850int INTERNAL(snd_pcm_hw_params_set_access_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *access); 851int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); 852int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); 853 854int INTERNAL(snd_pcm_hw_params_get_format)(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val); 855int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); 856int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); 857int INTERNAL(snd_pcm_hw_params_set_format_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format); 858int INTERNAL(snd_pcm_hw_params_set_format_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format); 859int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); 860void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); 861 862int INTERNAL(snd_pcm_hw_params_get_subformat)(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); 863int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat); 864int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat); 865int INTERNAL(snd_pcm_hw_params_set_subformat_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); 866int INTERNAL(snd_pcm_hw_params_set_subformat_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); 867int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); 868void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); 869 870int INTERNAL(snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *params, unsigned int *val); 871int INTERNAL(snd_pcm_hw_params_get_channels_min)(const snd_pcm_hw_params_t *params, unsigned int *val); 872int INTERNAL(snd_pcm_hw_params_get_channels_max)(const snd_pcm_hw_params_t *params, unsigned int *val); 873int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); 874int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); 875int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); 876int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); 877int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max); 878int INTERNAL(snd_pcm_hw_params_set_channels_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); 879int INTERNAL(snd_pcm_hw_params_set_channels_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); 880int INTERNAL(snd_pcm_hw_params_set_channels_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); 881 882int INTERNAL(snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 883int INTERNAL(snd_pcm_hw_params_get_rate_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 884int INTERNAL(snd_pcm_hw_params_get_rate_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 885int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 886int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 887int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 888int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 889int 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); 890int INTERNAL(snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 891int INTERNAL(snd_pcm_hw_params_set_rate_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 892int INTERNAL(snd_pcm_hw_params_set_rate_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 893 894int INTERNAL(snd_pcm_hw_params_get_period_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 895int INTERNAL(snd_pcm_hw_params_get_period_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 896int INTERNAL(snd_pcm_hw_params_get_period_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 897int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 898int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 899int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 900int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 901int 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); 902int INTERNAL(snd_pcm_hw_params_set_period_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 903int INTERNAL(snd_pcm_hw_params_set_period_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 904int INTERNAL(snd_pcm_hw_params_set_period_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 905 906int INTERNAL(snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); 907int INTERNAL(snd_pcm_hw_params_get_period_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); 908int INTERNAL(snd_pcm_hw_params_get_period_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); 909int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); 910int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); 911int 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); 912int 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); 913int 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); 914int 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); 915int 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); 916int 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); 917int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 918 919int INTERNAL(snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 920int INTERNAL(snd_pcm_hw_params_get_periods_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 921int INTERNAL(snd_pcm_hw_params_get_periods_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 922int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 923int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 924int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 925int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 926int 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); 927int INTERNAL(snd_pcm_hw_params_set_periods_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 928int INTERNAL(snd_pcm_hw_params_set_periods_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 929int INTERNAL(snd_pcm_hw_params_set_periods_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 930int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 931 932int INTERNAL(snd_pcm_hw_params_get_buffer_time)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 933int INTERNAL(snd_pcm_hw_params_get_buffer_time_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 934int INTERNAL(snd_pcm_hw_params_get_buffer_time_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 935int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 936int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 937int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 938int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 939int 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); 940int INTERNAL(snd_pcm_hw_params_set_buffer_time_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 941int INTERNAL(snd_pcm_hw_params_set_buffer_time_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 942int INTERNAL(snd_pcm_hw_params_set_buffer_time_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 943 944int INTERNAL(snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 945int INTERNAL(snd_pcm_hw_params_get_buffer_size_min)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 946int INTERNAL(snd_pcm_hw_params_get_buffer_size_max)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 947int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); 948int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); 949int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 950int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 951int 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); 952int INTERNAL(snd_pcm_hw_params_set_buffer_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 953int INTERNAL(snd_pcm_hw_params_set_buffer_size_first)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 954int INTERNAL(snd_pcm_hw_params_set_buffer_size_last)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 955 956int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val); 957int INTERNAL(snd_pcm_sw_params_get_tstamp_mode)(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val); 958int snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val); 959int snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val); 960int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 961int INTERNAL(snd_pcm_sw_params_get_avail_min)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 962int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 963int INTERNAL(snd_pcm_sw_params_get_start_threshold)(const snd_pcm_sw_params_t *paramsm, snd_pcm_uframes_t *val); 964int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 965int INTERNAL(snd_pcm_sw_params_get_stop_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 966int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 967int INTERNAL(snd_pcm_sw_params_get_silence_threshold)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 968int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 969int INTERNAL(snd_pcm_sw_params_get_silence_size)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 970#endif /* INTERNAL */ 971 972const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t param); 973void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params, 974 snd_pcm_hw_param_t var, snd_output_t *out); 975#if 0 976int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy, int order, 977 snd_pcm_hw_param_t var, 978 unsigned int best, 979 unsigned int mul); 980int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int order, 981 snd_pcm_hw_param_t var, 982 unsigned int count, 983 snd_pcm_hw_strategy_simple_choices_list_t *choices); 984#endif 985 986#define SCONF_MANDATORY 1 987#define SCONF_UNCHANGED 2 988 989int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf, 990 snd_config_t **pcm_conf, unsigned int count, ...); 991 992#define SND_PCM_APPEND (1<<8) 993 994int snd_pcm_open_named_slave(snd_pcm_t **pcmp, const char *name, 995 snd_config_t *root, 996 snd_config_t *conf, snd_pcm_stream_t stream, 997 int mode, snd_config_t *parent_conf); 998static inline int 999snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root, 1000 snd_config_t *conf, snd_pcm_stream_t stream, 1001 int mode, snd_config_t *parent_conf) 1002{ 1003 return snd_pcm_open_named_slave(pcmp, NULL, root, conf, stream, 1004 mode, parent_conf); 1005} 1006 1007#define snd_pcm_conf_generic_id(id) _snd_conf_generic_id(id) 1008 1009int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd, 1010 int sync_ptr_ioctl); 1011int __snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name, 1012 snd_pcm_t *slave, int close_slave); 1013 1014int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout); 1015 1016const snd_config_t *snd_pcm_rate_get_default_converter(snd_config_t *root); 1017 1018#define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS) 1019#define SND_PCM_HW_PARBIT_FORMAT (1U << SND_PCM_HW_PARAM_FORMAT) 1020#define SND_PCM_HW_PARBIT_SUBFORMAT (1U << SND_PCM_HW_PARAM_SUBFORMAT) 1021#define SND_PCM_HW_PARBIT_CHANNELS (1U << SND_PCM_HW_PARAM_CHANNELS) 1022#define SND_PCM_HW_PARBIT_RATE (1U << SND_PCM_HW_PARAM_RATE) 1023#define SND_PCM_HW_PARBIT_PERIOD_TIME (1U << SND_PCM_HW_PARAM_PERIOD_TIME) 1024#define SND_PCM_HW_PARBIT_PERIOD_SIZE (1U << SND_PCM_HW_PARAM_PERIOD_SIZE) 1025#define SND_PCM_HW_PARBIT_PERIODS (1U << SND_PCM_HW_PARAM_PERIODS) 1026#define SND_PCM_HW_PARBIT_BUFFER_TIME (1U << SND_PCM_HW_PARAM_BUFFER_TIME) 1027#define SND_PCM_HW_PARBIT_BUFFER_SIZE (1U << SND_PCM_HW_PARAM_BUFFER_SIZE) 1028#define SND_PCM_HW_PARBIT_SAMPLE_BITS (1U << SND_PCM_HW_PARAM_SAMPLE_BITS) 1029#define SND_PCM_HW_PARBIT_FRAME_BITS (1U << SND_PCM_HW_PARAM_FRAME_BITS) 1030#define SND_PCM_HW_PARBIT_PERIOD_BYTES (1U << SND_PCM_HW_PARAM_PERIOD_BYTES) 1031#define SND_PCM_HW_PARBIT_BUFFER_BYTES (1U << SND_PCM_HW_PARAM_BUFFER_BYTES) 1032#define SND_PCM_HW_PARBIT_TICK_TIME (1U << SND_PCM_HW_PARAM_TICK_TIME) 1033 1034 1035#define SND_PCM_ACCBIT_MMAP { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \ 1036 (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \ 1037 (1U << SND_PCM_ACCESS_MMAP_COMPLEX)) } 1038#define SND_PCM_ACCBIT_MMAPI { (1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) } 1039#define SND_PCM_ACCBIT_MMAPN { (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) } 1040#define SND_PCM_ACCBIT_MMAPC { (1U << SND_PCM_ACCESS_MMAP_COMPLEX) } 1041 1042#define SND_PCM_ACCBIT_SHM { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \ 1043 (1U << SND_PCM_ACCESS_RW_INTERLEAVED) | \ 1044 (1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \ 1045 (1U << SND_PCM_ACCESS_RW_NONINTERLEAVED)) } 1046#define SND_PCM_ACCBIT_SHMI { ((1U << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \ 1047 (1U << SND_PCM_ACCESS_RW_INTERLEAVED)) } 1048#define SND_PCM_ACCBIT_SHMN { ((1U << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \ 1049 (1U << SND_PCM_ACCESS_RW_NONINTERLEAVED)) } 1050 1051#define SND_PCM_FMTBIT_LINEAR \ 1052 { ((1U << SND_PCM_FORMAT_S8) | \ 1053 (1U << SND_PCM_FORMAT_U8) | \ 1054 (1U << SND_PCM_FORMAT_S16_LE) | \ 1055 (1U << SND_PCM_FORMAT_S16_BE) | \ 1056 (1U << SND_PCM_FORMAT_U16_LE) | \ 1057 (1U << SND_PCM_FORMAT_U16_BE) | \ 1058 (1U << SND_PCM_FORMAT_S20_LE) | \ 1059 (1U << SND_PCM_FORMAT_S20_BE) | \ 1060 (1U << SND_PCM_FORMAT_U20_LE) | \ 1061 (1U << SND_PCM_FORMAT_U20_BE) | \ 1062 (1U << SND_PCM_FORMAT_S24_LE) | \ 1063 (1U << SND_PCM_FORMAT_S24_BE) | \ 1064 (1U << SND_PCM_FORMAT_U24_LE) | \ 1065 (1U << SND_PCM_FORMAT_U24_BE) | \ 1066 (1U << SND_PCM_FORMAT_S32_LE) | \ 1067 (1U << SND_PCM_FORMAT_S32_BE) | \ 1068 (1U << SND_PCM_FORMAT_U32_LE) | \ 1069 (1U << SND_PCM_FORMAT_U32_BE)), \ 1070 ((1U << (SND_PCM_FORMAT_S24_3LE - 32)) | \ 1071 (1U << (SND_PCM_FORMAT_U24_3LE - 32)) | \ 1072 (1U << (SND_PCM_FORMAT_S24_3BE - 32)) | \ 1073 (1U << (SND_PCM_FORMAT_U24_3BE - 32)) | \ 1074 (1U << (SND_PCM_FORMAT_S20_3LE - 32)) | \ 1075 (1U << (SND_PCM_FORMAT_U20_3LE - 32)) | \ 1076 (1U << (SND_PCM_FORMAT_S20_3BE - 32)) | \ 1077 (1U << (SND_PCM_FORMAT_U20_3BE - 32)) | \ 1078 (1U << (SND_PCM_FORMAT_S18_3LE - 32)) | \ 1079 (1U << (SND_PCM_FORMAT_U18_3LE - 32)) | \ 1080 (1U << (SND_PCM_FORMAT_S18_3BE - 32)) | \ 1081 (1U << (SND_PCM_FORMAT_U18_3BE - 32))) } 1082 1083 1084#define SND_PCM_FMTBIT_FLOAT \ 1085 { ((1U << SND_PCM_FORMAT_FLOAT_LE) | \ 1086 (1U << SND_PCM_FORMAT_FLOAT_BE) | \ 1087 (1U << SND_PCM_FORMAT_FLOAT64_LE) | \ 1088 (1U << SND_PCM_FORMAT_FLOAT64_BE)) } 1089 1090 1091typedef union snd_tmp_float { 1092 float f; 1093 int32_t i; 1094} snd_tmp_float_t; 1095 1096typedef union snd_tmp_double { 1097 double d; 1098 int64_t l; 1099} snd_tmp_double_t; 1100 1101/* get the current timestamp */ 1102#ifdef HAVE_CLOCK_GETTIME 1103static inline void gettimestamp(snd_htimestamp_t *tstamp, 1104 snd_pcm_tstamp_type_t tstamp_type) 1105{ 1106 clockid_t id; 1107 1108 switch (tstamp_type) { 1109#ifdef CLOCK_MONOTONIC_RAW 1110 case SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW: 1111 id = CLOCK_MONOTONIC_RAW; 1112 break; 1113#endif 1114#ifdef CLOCK_MONOTONIC 1115 case SND_PCM_TSTAMP_TYPE_MONOTONIC: 1116 id = CLOCK_MONOTONIC; 1117 break; 1118#endif 1119 default: 1120 id = CLOCK_REALTIME; 1121 break; 1122 } 1123 clock_gettime(id, tstamp); 1124} 1125#else /* HAVE_CLOCK_GETTIME */ 1126static inline void gettimestamp(snd_htimestamp_t *tstamp, 1127 snd_pcm_tstamp_type_t tstamp_type) 1128{ 1129 struct timeval tv; 1130 1131 gettimeofday(&tv, 0); 1132 tstamp->tv_sec = tv.tv_sec; 1133 tstamp->tv_nsec = tv.tv_usec * 1000L; 1134} 1135#endif /* HAVE_CLOCK_GETTIME */ 1136 1137snd_pcm_chmap_query_t ** 1138_snd_pcm_make_single_query_chmaps(const snd_pcm_chmap_t *src); 1139snd_pcm_chmap_t *_snd_pcm_copy_chmap(const snd_pcm_chmap_t *src); 1140snd_pcm_chmap_query_t ** 1141_snd_pcm_copy_chmap_query(snd_pcm_chmap_query_t * const *src); 1142snd_pcm_chmap_query_t ** 1143_snd_pcm_parse_config_chmaps(snd_config_t *conf); 1144snd_pcm_chmap_t * 1145_snd_pcm_choose_fixed_chmap(snd_pcm_t *pcm, snd_pcm_chmap_query_t * const *maps); 1146 1147/* return true if the PCM stream may wait to get avail_min space */ 1148static inline int snd_pcm_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail) 1149{ 1150 if (avail >= pcm->avail_min) 1151 return 0; 1152 if (pcm->fast_ops->may_wait_for_avail_min) 1153 return pcm->fast_ops->may_wait_for_avail_min(pcm->fast_op_arg, avail); 1154 return 1; 1155} 1156 1157/* hack to access to internal period_event in snd_pcm_sw_parmams */ 1158static inline int sw_get_period_event(const snd_pcm_sw_params_t *params) 1159{ 1160 return params->reserved[sizeof(params->reserved) / sizeof(params->reserved[0])- 1]; 1161} 1162 1163static inline void sw_set_period_event(snd_pcm_sw_params_t *params, int val) 1164{ 1165 params->reserved[sizeof(params->reserved) / sizeof(params->reserved[0]) - 1] = val; 1166} 1167 1168#define PCMINABORT(pcm) (((pcm)->mode & SND_PCM_ABORT) != 0) 1169 1170static inline snd_pcm_sframes_t pcm_frame_diff(snd_pcm_uframes_t ptr1, 1171 snd_pcm_uframes_t ptr2, 1172 snd_pcm_uframes_t boundary) 1173{ 1174 if (ptr1 < ptr2) 1175 return ptr1 + (boundary - ptr2); 1176 else 1177 return ptr1 - ptr2; 1178} 1179 1180static inline snd_pcm_sframes_t pcm_frame_diff2(snd_pcm_uframes_t ptr1, 1181 snd_pcm_uframes_t ptr2, 1182 snd_pcm_uframes_t boundary) 1183{ 1184 snd_pcm_sframes_t r = ptr1 - ptr2; 1185 if (r >= (snd_pcm_sframes_t)boundary / 2) 1186 return boundary - r; 1187 return r; 1188} 1189 1190#ifdef THREAD_SAFE_API 1191/* 1192 * __snd_pcm_lock() and __snd_pcm_unlock() are used to lock/unlock the plugin 1193 * forcibly even if it's declared as thread-safe. It's needed only for some 1194 * codes that are thread-unsafe per design (e.g. snd_pcm_nonblock()). 1195 * 1196 * OTOH, snd_pcm_lock() and snd_pcm_unlock() are used to lock/unlock the plugin 1197 * in normal situations. They do lock/unlock only when the plugin is 1198 * thread-unsafe. 1199 * 1200 * Both __snd_pcm_lock() and snd_pcm_lock() (and their unlocks) wouldn't do 1201 * any action when the whole locking is disabled via $LIBASOUND_THREAD_SAFE=0. 1202 */ 1203static inline void __snd_pcm_lock(snd_pcm_t *pcm) 1204{ 1205 if (pcm->lock_enabled) 1206 pthread_mutex_lock(&pcm->lock); 1207} 1208static inline void __snd_pcm_unlock(snd_pcm_t *pcm) 1209{ 1210 if (pcm->lock_enabled) 1211 pthread_mutex_unlock(&pcm->lock); 1212} 1213static inline void snd_pcm_lock(snd_pcm_t *pcm) 1214{ 1215 if (pcm->lock_enabled && pcm->need_lock) 1216 pthread_mutex_lock(&pcm->lock); 1217} 1218static inline void snd_pcm_unlock(snd_pcm_t *pcm) 1219{ 1220 if (pcm->lock_enabled && pcm->need_lock) 1221 pthread_mutex_unlock(&pcm->lock); 1222} 1223#else /* THREAD_SAFE_API */ 1224#define __snd_pcm_lock(pcm) do {} while (0) 1225#define __snd_pcm_unlock(pcm) do {} while (0) 1226#define snd_pcm_lock(pcm) do {} while (0) 1227#define snd_pcm_unlock(pcm) do {} while (0) 1228#endif /* THREAD_SAFE_API */ 1229 1230#endif /* __PCM_LOCAL_H */ 1231