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