~ubuntu-branches/ubuntu/warty/alsa-lib/warty

« back to all changes in this revision

Viewing changes to src/pcm/mask_inline.h

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-09-23 19:38:45 UTC
  • Revision ID: james.westby@ubuntu.com-20040923193845-71lrqesgxij0yzn7
Tags: upstream-1.0.5
ImportĀ upstreamĀ versionĀ 1.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Mask inlines
 
3
 *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
 
4
 *
 
5
 *
 
6
 *   This library is free software; you can redistribute it and/or modify
 
7
 *   it under the terms of the GNU Lesser General Public License as
 
8
 *   published by the Free Software Foundation; either version 2.1 of
 
9
 *   the License, or (at your option) any later version.
 
10
 *
 
11
 *   This program is distributed in the hope that it will be useful,
 
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *   GNU Lesser General Public License for more details.
 
15
 *
 
16
 *   You should have received a copy of the GNU Lesser General Public
 
17
 *   License along with this library; if not, write to the Free Software
 
18
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
19
 *
 
20
 */
 
21
  
 
22
#include <sys/types.h>
 
23
 
 
24
#define MASK_INLINE static inline
 
25
 
 
26
#define MASK_MAX SND_MASK_MAX
 
27
#define MASK_SIZE (MASK_MAX / 32)
 
28
 
 
29
#define MASK_OFS(i)     ((i) >> 5)
 
30
#define MASK_BIT(i)     (1U << ((i) & 31))
 
31
 
 
32
MASK_INLINE unsigned int ld2(u_int32_t v)
 
33
{
 
34
        unsigned r = 0;
 
35
 
 
36
        if (v >= 0x10000) {
 
37
                v >>= 16;
 
38
                r += 16;
 
39
        }
 
40
        if (v >= 0x100) {
 
41
                v >>= 8;
 
42
                r += 8;
 
43
        }
 
44
        if (v >= 0x10) {
 
45
                v >>= 4;
 
46
                r += 4;
 
47
        }
 
48
        if (v >= 4) {
 
49
                v >>= 2;
 
50
                r += 2;
 
51
        }
 
52
        if (v >= 2)
 
53
                r++;
 
54
        return r;
 
55
}
 
56
 
 
57
MASK_INLINE unsigned int hweight32(u_int32_t v)
 
58
{
 
59
        v = (v & 0x55555555) + ((v >> 1) & 0x55555555);
 
60
        v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
 
61
        v = (v & 0x0F0F0F0F) + ((v >> 4) & 0x0F0F0F0F);
 
62
        v = (v & 0x00FF00FF) + ((v >> 8) & 0x00FF00FF);
 
63
        return (v & 0x0000FFFF) + ((v >> 16) & 0x0000FFFF);
 
64
}
 
65
 
 
66
MASK_INLINE size_t snd_mask_sizeof(void)
 
67
{
 
68
        return sizeof(snd_mask_t);
 
69
}
 
70
 
 
71
MASK_INLINE void snd_mask_none(snd_mask_t *mask)
 
72
{
 
73
        memset(mask, 0, sizeof(*mask));
 
74
}
 
75
 
 
76
MASK_INLINE void snd_mask_any(snd_mask_t *mask)
 
77
{
 
78
        memset(mask, 0xff, MASK_SIZE * sizeof(u_int32_t));
 
79
}
 
80
 
 
81
MASK_INLINE int snd_mask_empty(const snd_mask_t *mask)
 
82
{
 
83
        int i;
 
84
        for (i = 0; i < MASK_SIZE; i++)
 
85
                if (mask->bits[i])
 
86
                        return 0;
 
87
        return 1;
 
88
}
 
89
 
 
90
MASK_INLINE int snd_mask_full(const snd_mask_t *mask)
 
91
{
 
92
        int i;
 
93
        for (i = 0; i < MASK_SIZE; i++)
 
94
                if (mask->bits[i] != 0xffffffff)
 
95
                        return 0;
 
96
        return 1;
 
97
}
 
98
 
 
99
MASK_INLINE unsigned int snd_mask_count(const snd_mask_t *mask)
 
100
{
 
101
        int i, w = 0;
 
102
        for (i = 0; i < MASK_SIZE; i++)
 
103
                w += hweight32(mask->bits[i]);
 
104
        return w;
 
105
}
 
106
 
 
107
MASK_INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
 
108
{
 
109
        int i;
 
110
        assert(!snd_mask_empty(mask));
 
111
        for (i = 0; i < MASK_SIZE; i++) {
 
112
                if (mask->bits[i])
 
113
                        return ffs(mask->bits[i]) - 1 + (i << 5);
 
114
        }
 
115
        return 0;
 
116
}
 
117
 
 
118
MASK_INLINE unsigned int snd_mask_max(const snd_mask_t *mask)
 
119
{
 
120
        int i;
 
121
        assert(!snd_mask_empty(mask));
 
122
        for (i = MASK_SIZE - 1; i >= 0; i--) {
 
123
                if (mask->bits[i])
 
124
                        return ld2(mask->bits[i]) + (i << 5);
 
125
        }
 
126
        return 0;
 
127
}
 
128
 
 
129
MASK_INLINE void snd_mask_set(snd_mask_t *mask, unsigned int val)
 
130
{
 
131
        assert(val <= SND_MASK_MAX);
 
132
        mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
 
133
}
 
134
 
 
135
MASK_INLINE void snd_mask_reset(snd_mask_t *mask, unsigned int val)
 
136
{
 
137
        assert(val <= SND_MASK_MAX);
 
138
        mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
 
139
}
 
140
 
 
141
MASK_INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
 
142
{
 
143
        unsigned int i;
 
144
        assert(to <= SND_MASK_MAX && from <= to);
 
145
        for (i = from; i <= to; i++)
 
146
                mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
 
147
}
 
148
 
 
149
MASK_INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
 
150
{
 
151
        unsigned int i;
 
152
        assert(to <= SND_MASK_MAX && from <= to);
 
153
        for (i = from; i <= to; i++)
 
154
                mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
 
155
}
 
156
 
 
157
MASK_INLINE void snd_mask_leave(snd_mask_t *mask, unsigned int val)
 
158
{
 
159
        unsigned int v;
 
160
        assert(val <= SND_MASK_MAX);
 
161
        v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
 
162
        snd_mask_none(mask);
 
163
        mask->bits[MASK_OFS(val)] = v;
 
164
}
 
165
 
 
166
MASK_INLINE void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v)
 
167
{
 
168
        int i;
 
169
        for (i = 0; i < MASK_SIZE; i++)
 
170
                mask->bits[i] &= v->bits[i];
 
171
}
 
172
 
 
173
MASK_INLINE void snd_mask_union(snd_mask_t *mask, const snd_mask_t *v)
 
174
{
 
175
        int i;
 
176
        for (i = 0; i < MASK_SIZE; i++)
 
177
                mask->bits[i] |= v->bits[i];
 
178
}
 
179
 
 
180
MASK_INLINE int snd_mask_eq(const snd_mask_t *mask, const snd_mask_t *v)
 
181
{
 
182
        return ! memcmp(mask, v, MASK_SIZE * 4);
 
183
}
 
184
 
 
185
MASK_INLINE void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v)
 
186
{
 
187
        *mask = *v;
 
188
}
 
189
 
 
190
MASK_INLINE int snd_mask_test(const snd_mask_t *mask, unsigned int val)
 
191
{
 
192
        assert(val <= SND_MASK_MAX);
 
193
        return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
 
194
}
 
195
 
 
196
MASK_INLINE int snd_mask_single(const snd_mask_t *mask)
 
197
{
 
198
        int i, c = 0;
 
199
        assert(!snd_mask_empty(mask));
 
200
        for (i = 0; i < MASK_SIZE; i++) {
 
201
                if (! mask->bits[i])
 
202
                        continue;
 
203
                if (mask->bits[i] & (mask->bits[i] - 1))
 
204
                        return 0;
 
205
                if (c)
 
206
                        return 0;
 
207
                c++;
 
208
        }
 
209
        return 1;
 
210
}
 
211
 
 
212
MASK_INLINE int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v)
 
213
{
 
214
        snd_mask_t old;
 
215
        if (snd_mask_empty(mask))
 
216
                return -ENOENT;
 
217
        snd_mask_copy(&old, mask);
 
218
        snd_mask_intersect(mask, v);
 
219
        if (snd_mask_empty(mask))
 
220
                return -EINVAL;
 
221
        return !snd_mask_eq(mask, &old);
 
222
}
 
223
 
 
224
MASK_INLINE int snd_mask_refine_first(snd_mask_t *mask)
 
225
{
 
226
        if (snd_mask_empty(mask))
 
227
                return -ENOENT;
 
228
        if (snd_mask_single(mask))
 
229
                return 0;
 
230
        snd_mask_leave(mask, snd_mask_min(mask));
 
231
        return 1;
 
232
}
 
233
 
 
234
MASK_INLINE int snd_mask_refine_last(snd_mask_t *mask)
 
235
{
 
236
        if (snd_mask_empty(mask))
 
237
                return -ENOENT;
 
238
        if (snd_mask_single(mask))
 
239
                return 0;
 
240
        snd_mask_leave(mask, snd_mask_max(mask));
 
241
        return 1;
 
242
}
 
243
 
 
244
MASK_INLINE int snd_mask_refine_min(snd_mask_t *mask, unsigned int val)
 
245
{
 
246
        if (snd_mask_empty(mask))
 
247
                return -ENOENT;
 
248
        if (snd_mask_min(mask) >= val)
 
249
                return 0;
 
250
        snd_mask_reset_range(mask, 0, val - 1);
 
251
        if (snd_mask_empty(mask))
 
252
                return -EINVAL;
 
253
        return 1;
 
254
}
 
255
 
 
256
MASK_INLINE int snd_mask_refine_max(snd_mask_t *mask, unsigned int val)
 
257
{
 
258
        if (snd_mask_empty(mask))
 
259
                return -ENOENT;
 
260
        if (snd_mask_max(mask) <= val)
 
261
                return 0;
 
262
        snd_mask_reset_range(mask, val + 1, SND_MASK_MAX);
 
263
        if (snd_mask_empty(mask))
 
264
                return -EINVAL;
 
265
        return 1;
 
266
}
 
267
 
 
268
MASK_INLINE int snd_mask_refine_set(snd_mask_t *mask, unsigned int val)
 
269
{
 
270
        int changed;
 
271
        if (snd_mask_empty(mask))
 
272
                return -ENOENT;
 
273
        changed = !snd_mask_single(mask);
 
274
        snd_mask_leave(mask, val);
 
275
        if (snd_mask_empty(mask))
 
276
                return -EINVAL;
 
277
        return changed;
 
278
}
 
279
 
 
280
MASK_INLINE int snd_mask_value(const snd_mask_t *mask)
 
281
{
 
282
        assert(!snd_mask_empty(mask));
 
283
        return snd_mask_min(mask);
 
284
}
 
285
 
 
286
MASK_INLINE int snd_mask_always_eq(const snd_mask_t *m1, const snd_mask_t *m2)
 
287
{
 
288
        return snd_mask_single(m1) && snd_mask_single(m2) &&
 
289
                snd_mask_value(m1) == snd_mask_value(m2);
 
290
}
 
291
 
 
292
MASK_INLINE int snd_mask_never_eq(const snd_mask_t *m1, const snd_mask_t *m2)
 
293
{
 
294
        int i;
 
295
        for (i = 0; i < MASK_SIZE; i++)
 
296
                if (m1->bits[i] & m2->bits[i])
 
297
                        return 0;
 
298
        return 1;
 
299
}