source: GPL/branches/alsa-resync1/alsa-kernel/include/sound/pcm_params.h@ 210

Last change on this file since 210 was 210, checked in by Brendan Oakley, 18 years ago

Merged to Alsa 0.9.0rc3

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