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 (at) 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 int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 26 struct snd_pcm_hw_params *params, 27 snd_pcm_hw_param_t var, int *dir); 28 int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 29 struct snd_pcm_hw_params *params, 30 snd_pcm_hw_param_t var, int *dir); 31 int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 32 snd_pcm_hw_param_t var, int *dir); 33 34 #define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 35 #define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 36 #define MASK_OFS(i) ((i) >> 5) 37 #define MASK_BIT(i) (1U << ((i) & 31)) 38 39 static inline unsigned int ld2(u_int32_t v) 40 { 41 unsigned r = 0; 42 43 if (v >= 0x10000) { 44 v >>= 16; 45 r += 16; 46 } 47 if (v >= 0x100) { 48 v >>= 8; 49 r += 8; 50 } 51 if (v >= 0x10) { 52 v >>= 4; 53 r += 4; 54 } 55 if (v >= 4) { 56 v >>= 2; 57 r += 2; 58 } 59 if (v >= 2) 60 r++; 61 return r; 62 } 63 64 static inline size_t snd_mask_sizeof(void) 65 { 66 return sizeof(struct snd_mask); 67 } 68 69 static inline void snd_mask_none(struct snd_mask *mask) 70 { 71 memset(mask, 0, sizeof(*mask)); 72 } 73 74 static inline void snd_mask_any(struct snd_mask *mask) 75 { 76 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 77 } 78 79 static inline int snd_mask_empty(const struct snd_mask *mask) 80 { 81 int i; 82 for (i = 0; i < SNDRV_MASK_SIZE; i++) 83 if (mask->bits[i]) 84 return 0; 85 return 1; 86 } 87 88 static inline unsigned int snd_mask_min(const struct snd_mask *mask) 89 { 90 int i; 91 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 92 if (mask->bits[i]) 93 return ffs(mask->bits[i]) - 1 + (i << 5); 94 } 95 return 0; 96 } 97 98 static inline unsigned int snd_mask_max(const struct snd_mask *mask) 99 { 100 int i; 101 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) { 102 if (mask->bits[i]) 103 return ld2(mask->bits[i]) + (i << 5); 104 } 105 return 0; 106 } 107 108 static inline void snd_mask_set(struct snd_mask *mask, unsigned int val) 109 { 110 mask->bits[MASK_OFS(val)] |= MASK_BIT(val); 111 } 112 113 static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val) 114 { 115 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val); 116 } 117 118 static inline void snd_mask_set_range(struct snd_mask *mask, 119 unsigned int from, unsigned int to) 120 { 121 unsigned int i; 122 for (i = from; i <= to; i++) 123 mask->bits[MASK_OFS(i)] |= MASK_BIT(i); 124 } 125 126 static inline void snd_mask_reset_range(struct snd_mask *mask, 127 unsigned int from, unsigned int to) 128 { 129 unsigned int i; 130 for (i = from; i <= to; i++) 131 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); 132 } 133 134 static inline void snd_mask_leave(struct snd_mask *mask, unsigned int val) 135 { 136 unsigned int v; 137 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val); 138 snd_mask_none(mask); 139 mask->bits[MASK_OFS(val)] = v; 140 } 141 142 static inline void snd_mask_intersect(struct snd_mask *mask, 143 const struct snd_mask *v) 144 { 145 int i; 146 for (i = 0; i < SNDRV_MASK_SIZE; i++) 147 mask->bits[i] &= v->bits[i]; 148 } 149 150 static inline int snd_mask_eq(const struct snd_mask *mask, 151 const struct snd_mask *v) 152 { 153 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 154 } 155 156 static inline void snd_mask_copy(struct snd_mask *mask, 157 const struct snd_mask *v) 158 { 159 *mask = *v; 160 } 161 162 static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val) 163 { 164 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 165 } 166 167 static inline int snd_mask_single(const struct snd_mask *mask) 168 { 169 int i, c = 0; 170 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 171 if (! mask->bits[i]) 172 continue; 173 if (mask->bits[i] & (mask->bits[i] - 1)) 174 return 0; 175 if (c) 176 return 0; 177 c++; 178 } 179 return 1; 180 } 181 182 static inline int snd_mask_refine(struct snd_mask *mask, 183 const struct snd_mask *v) 184 { 185 struct snd_mask old; 186 snd_mask_copy(&old, mask); 187 snd_mask_intersect(mask, v); 188 if (snd_mask_empty(mask)) 189 return -EINVAL; 190 return !snd_mask_eq(mask, &old); 191 } 192 193 static inline int snd_mask_refine_first(struct snd_mask *mask) 194 { 195 if (snd_mask_single(mask)) 196 return 0; 197 snd_mask_leave(mask, snd_mask_min(mask)); 198 return 1; 199 } 200 201 static inline int snd_mask_refine_last(struct snd_mask *mask) 202 { 203 if (snd_mask_single(mask)) 204 return 0; 205 snd_mask_leave(mask, snd_mask_max(mask)); 206 return 1; 207 } 208 209 static inline int snd_mask_refine_min(struct snd_mask *mask, unsigned int val) 210 { 211 if (snd_mask_min(mask) >= val) 212 return 0; 213 snd_mask_reset_range(mask, 0, val - 1); 214 if (snd_mask_empty(mask)) 215 return -EINVAL; 216 return 1; 217 } 218 219 static inline int snd_mask_refine_max(struct snd_mask *mask, unsigned int val) 220 { 221 if (snd_mask_max(mask) <= val) 222 return 0; 223 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS); 224 if (snd_mask_empty(mask)) 225 return -EINVAL; 226 return 1; 227 } 228 229 static inline int snd_mask_refine_set(struct snd_mask *mask, unsigned int val) 230 { 231 int changed; 232 changed = !snd_mask_single(mask); 233 snd_mask_leave(mask, val); 234 if (snd_mask_empty(mask)) 235 return -EINVAL; 236 return changed; 237 } 238 239 static inline int snd_mask_value(const struct snd_mask *mask) 240 { 241 return snd_mask_min(mask); 242 } 243 244 static inline void snd_interval_any(struct snd_interval *i) 245 { 246 i->min = 0; 247 i->openmin = 0; 248 i->max = UINT_MAX; 249 i->openmax = 0; 250 i->integer = 0; 251 i->empty = 0; 252 } 253 254 static inline void snd_interval_none(struct snd_interval *i) 255 { 256 i->empty = 1; 257 } 258 259 static inline int snd_interval_checkempty(const struct snd_interval *i) 260 { 261 return (i->min > i->max || 262 (i->min == i->max && (i->openmin || i->openmax))); 263 } 264 265 static inline int snd_interval_empty(const struct snd_interval *i) 266 { 267 return i->empty; 268 } 269 270 static inline int snd_interval_single(const struct snd_interval *i) 271 { 272 return (i->min == i->max || 273 (i->min + 1 == i->max && i->openmax)); 274 } 275 276 static inline int snd_interval_value(const struct snd_interval *i) 277 { 278 return i->min; 279 } 280 281 static inline int snd_interval_min(const struct snd_interval *i) 282 { 283 return i->min; 284 } 285 286 static inline int snd_interval_max(const struct snd_interval *i) 287 { 288 unsigned int v; 289 v = i->max; 290 if (i->openmax) 291 v--; 292 return v; 293 } 294 295 static inline int snd_interval_test(const struct snd_interval *i, unsigned int val) 296 { 297 return !((i->min > val || (i->min == val && i->openmin) || 298 i->max < val || (i->max == val && i->openmax))); 299 } 300 301 static inline void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s) 302 { 303 *d = *s; 304 } 305 306 static inline int snd_interval_setinteger(struct snd_interval *i) 307 { 308 if (i->integer) 309 return 0; 310 if (i->openmin && i->openmax && i->min == i->max) 311 return -EINVAL; 312 i->integer = 1; 313 return 1; 314 } 315 316 static inline int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2) 317 { 318 if (i1->empty) 319 return i2->empty; 320 if (i2->empty) 321 return i1->empty; 322 return i1->min == i2->min && i1->openmin == i2->openmin && 323 i1->max == i2->max && i1->openmax == i2->openmax; 324 } 325 326 static inline unsigned int add(unsigned int a, unsigned int b) 327 { 328 if (a >= UINT_MAX - b) 329 return UINT_MAX; 330 return a + b; 331 } 332 333 static inline unsigned int sub(unsigned int a, unsigned int b) 334 { 335 if (a > b) 336 return a - b; 337 return 0; 338 } 339 340 #endif /* __SOUND_PCM_PARAMS_H */ 341 342