1 #ifndef __SOUND_PCM_PARAMS_H 2 #define __SOUND_PCM_PARAMS_H 3 4 /* 5 * PCM params helpers 6 * Copyright (c) by Abramo Bagnara <abramo@alsa-project.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25 extern int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, 26 snd_pcm_hw_param_t var, const struct snd_mask *val); 27 extern unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, 28 snd_pcm_hw_param_t var, int *dir); 29 extern unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, 30 snd_pcm_hw_param_t var, int *dir); 31 extern int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 32 snd_pcm_hw_param_t var, unsigned int val, int dir); 33 extern int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, 34 snd_pcm_hw_param_t var); 35 extern int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, 36 snd_pcm_hw_param_t var, unsigned int val, int dir); 37 38 /* To share the same code we have alsa-lib */ 39 #define INLINE static inline 40 #define assert(a) (void)(a) 41 42 #define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 43 #define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 44 #define MASK_OFS(i) ((i) >> 5) 45 #define MASK_BIT(i) (1U << ((i) & 31)) 46 47 INLINE unsigned int ld2(u_int32_t v) 48 { 49 unsigned r = 0; 50 51 if (v >= 0x10000) { 52 v >>= 16; 53 r += 16; 54 } 55 if (v >= 0x100) { 56 v >>= 8; 57 r += 8; 58 } 59 if (v >= 0x10) { 60 v >>= 4; 61 r += 4; 62 } 63 if (v >= 4) { 64 v >>= 2; 65 r += 2; 66 } 67 if (v >= 2) 68 r++; 69 return r; 70 } 71 72 INLINE size_t snd_mask_sizeof(void) 73 { 74 return sizeof(struct snd_mask); 75 } 76 77 INLINE void snd_mask_none(struct snd_mask *mask) 78 { 79 memset(mask, 0, sizeof(*mask)); 80 } 81 82 INLINE void snd_mask_any(struct snd_mask *mask) 83 { 84 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 85 } 86 87 INLINE int snd_mask_empty(const struct snd_mask *mask) 88 { 89 int i; 90 for (i = 0; i < SNDRV_MASK_SIZE; i++) 91 if (mask->bits[i]) 92 return 0; 93 return 1; 94 } 95 96 INLINE unsigned int snd_mask_min(const struct snd_mask *mask) 97 { 98 int i; 99 assert(!snd_mask_empty(mask)); 100 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 101 if (mask->bits[i]) 102 return ffs(mask->bits[i]) - 1 + (i << 5); 103 } 104 return 0; 105 } 106 107 INLINE unsigned int snd_mask_max(const struct snd_mask *mask) 108 { 109 int i; 110 assert(!snd_mask_empty(mask)); 111 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) { 112 if (mask->bits[i]) 113 return ld2(mask->bits[i]) + (i << 5); 114 } 115 return 0; 116 } 117 118 INLINE void snd_mask_set(struct snd_mask *mask, unsigned int val) 119 { 120 assert(val <= SNDRV_MASK_BITS); 121 mask->bits[MASK_OFS(val)] |= MASK_BIT(val); 122 } 123 124 INLINE void snd_mask_reset(struct snd_mask *mask, unsigned int val) 125 { 126 assert(val <= SNDRV_MASK_BITS); 127 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val); 128 } 129 130 INLINE void snd_mask_set_range(struct snd_mask *mask, unsigned int from, unsigned int to) 131 { 132 unsigned int i; 133 assert(to <= SNDRV_MASK_BITS && from <= to); 134 for (i = from; i <= to; i++) 135 mask->bits[MASK_OFS(i)] |= MASK_BIT(i); 136 } 137 138 INLINE void snd_mask_reset_range(struct snd_mask *mask, unsigned int from, unsigned int to) 139 { 140 unsigned int i; 141 assert(to <= SNDRV_MASK_BITS && from <= to); 142 for (i = from; i <= to; i++) 143 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); 144 } 145 146 INLINE void snd_mask_leave(struct snd_mask *mask, unsigned int val) 147 { 148 unsigned int v; 149 assert(val <= SNDRV_MASK_BITS); 150 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val); 151 snd_mask_none(mask); 152 mask->bits[MASK_OFS(val)] = v; 153 } 154 155 INLINE void snd_mask_intersect(struct snd_mask *mask, const struct snd_mask *v) 156 { 157 int i; 158 for (i = 0; i < SNDRV_MASK_SIZE; i++) 159 mask->bits[i] &= v->bits[i]; 160 } 161 162 INLINE int snd_mask_eq(const struct snd_mask *mask, const struct snd_mask *v) 163 { 164 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 165 } 166 167 INLINE void snd_mask_copy(struct snd_mask *mask, const struct snd_mask *v) 168 { 169 *mask = *v; 170 } 171 172 INLINE int snd_mask_test(const struct snd_mask *mask, unsigned int val) 173 { 174 assert(val <= SNDRV_MASK_BITS); 175 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 176 } 177 178 INLINE int snd_mask_single(const struct snd_mask *mask) 179 { 180 int i, c = 0; 181 assert(!snd_mask_empty(mask)); 182 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 183 if (! mask->bits[i]) 184 continue; 185 if (mask->bits[i] & (mask->bits[i] - 1)) 186 return 0; 187 if (c) 188 return 0; 189 c++; 190 } 191 return 1; 192 } 193 194 INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v) 195 { 196 struct snd_mask old; 197 assert(!snd_mask_empty(mask)); 198 snd_mask_copy(&old, mask); 199 snd_mask_intersect(mask, v); 200 if (snd_mask_empty(mask)) 201 return -EINVAL; 202 return !snd_mask_eq(mask, &old); 203 } 204 205 INLINE int snd_mask_refine_first(struct snd_mask *mask) 206 { 207 assert(!snd_mask_empty(mask)); 208 if (snd_mask_single(mask)) 209 return 0; 210 snd_mask_leave(mask, snd_mask_min(mask)); 211 return 1; 212 } 213 214 INLINE int snd_mask_refine_last(struct snd_mask *mask) 215 { 216 assert(!snd_mask_empty(mask)); 217 if (snd_mask_single(mask)) 218 return 0; 219 snd_mask_leave(mask, snd_mask_max(mask)); 220 return 1; 221 } 222 223 INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val) 224 { 225 assert(!snd_mask_empty(mask)); 226 if (snd_mask_min(mask) >= val) 227 return 0; 228 snd_mask_reset_range(mask, 0, val - 1); 229 if (snd_mask_empty(mask)) 230 return -EINVAL; 231 return 1; 232 } 233 234 INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val) 235 { 236 assert(!snd_mask_empty(mask)); 237 if (snd_mask_max(mask) <= val) 238 return 0; 239 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS); 240 if (snd_mask_empty(mask)) 241 return -EINVAL; 242 return 1; 243 } 244 245 INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val) 246 { 247 int changed; 248 assert(!snd_mask_empty(mask)); 249 changed = !snd_mask_single(mask); 250 snd_mask_leave(mask, val); 251 if (snd_mask_empty(mask)) 252 return -EINVAL; 253 return changed; 254 } 255 256 INLINE int snd_mask_value(const struct snd_mask *mask) 257 { 258 assert(!snd_mask_empty(mask)); 259 return snd_mask_min(mask); 260 } 261 262 INLINE void snd_interval_any(struct snd_interval *i) 263 { 264 i->min = 0; 265 i->openmin = 0; 266 i->max = UINT_MAX; 267 i->openmax = 0; 268 i->integer = 0; 269 i->empty = 0; 270 } 271 272 INLINE void snd_interval_none(struct snd_interval *i) 273 { 274 i->empty = 1; 275 } 276 277 INLINE int snd_interval_checkempty(const struct snd_interval *i) 278 { 279 return (i->min > i->max || 280 (i->min == i->max && (i->openmin || i->openmax))); 281 } 282 283 INLINE int snd_interval_empty(const struct snd_interval *i) 284 { 285 return i->empty; 286 } 287 288 INLINE int snd_interval_single(const struct snd_interval *i) 289 { 290 assert(!snd_interval_empty(i)); 291 return (i->min == i->max || 292 (i->min + 1 == i->max && i->openmax)); 293 } 294 295 INLINE int snd_interval_value(const struct snd_interval *i) 296 { 297 assert(snd_interval_single(i)); 298 return i->min; 299 } 300 301 INLINE int snd_interval_min(const struct snd_interval *i) 302 { 303 assert(!snd_interval_empty(i)); 304 return i->min; 305 } 306 307 INLINE int snd_interval_max(const struct snd_interval *i) 308 { 309 unsigned int v; 310 assert(!snd_interval_empty(i)); 311 v = i->max; 312 if (i->openmax) 313 v--; 314 return v; 315 } 316 317 INLINE int snd_interval_test(const struct snd_interval *i, unsigned int val) 318 { 319 return !((i->min > val || (i->min == val && i->openmin) || 320 i->max < val || (i->max == val && i->openmax))); 321 } 322 323 INLINE void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s) 324 { 325 *d = *s; 326 } 327 328 INLINE int snd_interval_setinteger(struct snd_interval *i) 329 { 330 if (i->integer) 331 return 0; 332 if (i->openmin && i->openmax && i->min == i->max) 333 return -EINVAL; 334 i->integer = 1; 335 return 1; 336 } 337 338 INLINE int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2) 339 { 340 if (i1->empty) 341 return i2->empty; 342 if (i2->empty) 343 return i1->empty; 344 return i1->min == i2->min && i1->openmin == i2->openmin && 345 i1->max == i2->max && i1->openmax == i2->openmax; 346 } 347 348 static inline unsigned int add(unsigned int a, unsigned int b) 349 { 350 if (a >= UINT_MAX - b) 351 return UINT_MAX; 352 return a + b; 353 } 354 355 static inline unsigned int sub(unsigned int a, unsigned int b) 356 { 357 if (a > b) 358 return a - b; 359 return 0; 360 } 361 362 #undef INLINE 363 #undef assert 364 365 #endif /* __SOUND_PCM_PARAMS_H */ 366 367