]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sound/pcm/pcm.h
MFV r358616:
[FreeBSD/FreeBSD.git] / sys / dev / sound / pcm / pcm.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2006-2009 Ariff Abdullah <ariff@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 #ifndef _SND_PCM_H_
32 #define _SND_PCM_H_
33
34 #include <sys/param.h>
35
36 /*
37  * Macros for reading/writing PCM sample / int values from bytes array.
38  * Since every process is done using signed integer (and to make our life
39  * less miserable), unsigned sample will be converted to its signed
40  * counterpart and restored during writing back. To avoid overflow,
41  * we truncate 32bit (and only 32bit) samples down to 24bit (see below
42  * for the reason), unless SND_PCM_64 is defined.
43  */
44
45 /*
46  * Automatically turn on 64bit arithmetic on suitable archs
47  * (amd64 64bit, etc..) for wider 32bit samples / integer processing.
48  */
49 #if LONG_BIT >= 64
50 #undef SND_PCM_64
51 #define SND_PCM_64      1
52 #endif
53
54 typedef int32_t intpcm_t;
55
56 typedef int32_t intpcm8_t;
57 typedef int32_t intpcm16_t;
58 typedef int32_t intpcm24_t;
59
60 typedef uint32_t uintpcm_t;
61
62 typedef uint32_t uintpcm8_t;
63 typedef uint32_t uintpcm16_t;
64 typedef uint32_t uintpcm24_t;
65
66 #ifdef SND_PCM_64
67 typedef int64_t  intpcm32_t;
68 typedef uint64_t uintpcm32_t;
69 #else
70 typedef int32_t  intpcm32_t;
71 typedef uint32_t uintpcm32_t;
72 #endif
73
74 typedef int64_t intpcm64_t;
75 typedef uint64_t uintpcm64_t;
76
77 /* 32bit fixed point shift */
78 #define PCM_FXSHIFT     8
79
80 #define PCM_S8_MAX        0x7f
81 #define PCM_S8_MIN       -0x80
82 #define PCM_S16_MAX       0x7fff
83 #define PCM_S16_MIN      -0x8000
84 #define PCM_S24_MAX       0x7fffff
85 #define PCM_S24_MIN      -0x800000
86 #ifdef SND_PCM_64
87 #if LONG_BIT >= 64
88 #define PCM_S32_MAX       0x7fffffffL
89 #define PCM_S32_MIN      -0x80000000L
90 #else
91 #define PCM_S32_MAX       0x7fffffffLL
92 #define PCM_S32_MIN      -0x80000000LL
93 #endif
94 #else
95 #define PCM_S32_MAX       0x7fffffff
96 #define PCM_S32_MIN     (-0x7fffffff - 1)
97 #endif
98
99 /* Bytes-per-sample definition */
100 #define PCM_8_BPS       1
101 #define PCM_16_BPS      2
102 #define PCM_24_BPS      3
103 #define PCM_32_BPS      4
104
105 #define INTPCM_T(v)     ((intpcm_t)(v))
106 #define INTPCM8_T(v)    ((intpcm8_t)(v))
107 #define INTPCM16_T(v)   ((intpcm16_t)(v))
108 #define INTPCM24_T(v)   ((intpcm24_t)(v))
109 #define INTPCM32_T(v)   ((intpcm32_t)(v))
110
111 #if BYTE_ORDER == LITTLE_ENDIAN
112 #define _PCM_READ_S16_LE(b8)            INTPCM_T(*((int16_t *)(b8)))
113 #define _PCM_READ_S32_LE(b8)            INTPCM_T(*((int32_t *)(b8)))
114 #define _PCM_READ_S16_BE(b8)                                            \
115         INTPCM_T((b8)[1] | (((int8_t)((b8)[0])) << 8))
116 #define _PCM_READ_S32_BE(b8)                                            \
117         INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) |           \
118             (((int8_t)((b8)[0])) << 24))
119
120 #define _PCM_WRITE_S16_LE(b8, val)      do {                            \
121         *((int16_t *)(b8)) = (val);                                     \
122 } while (0)
123 #define _PCM_WRITE_S32_LE(b8, val)      do {                            \
124         *((int32_t *)(b8)) = (val);                                     \
125 } while (0)
126 #define _PCM_WRITE_S16_BE(bb8, vval)    do {                            \
127         intpcm_t val = (vval);                                          \
128         uint8_t *b8 = (bb8);                                            \
129         b8[1] = val;                                                    \
130         b8[0] = val >> 8;                                               \
131 } while (0)
132 #define _PCM_WRITE_S32_BE(bb8, vval)    do {                            \
133         intpcm_t val = (vval);                                          \
134         uint8_t *b8 = (bb8);                                            \
135         b8[3] = val;                                                    \
136         b8[2] = val >> 8;                                               \
137         b8[1] = val >> 16;                                              \
138         b8[0] = val >> 24;                                              \
139 } while (0)
140
141 #define _PCM_READ_U16_LE(b8)                                            \
142         INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
143 #define _PCM_READ_U32_LE(b8)                                            \
144         INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
145 #define _PCM_READ_U16_BE(b8)                                            \
146         INTPCM_T((b8)[1] | (((int8_t)((b8)[0] ^ 0x80)) << 8))
147 #define _PCM_READ_U32_BE(b8)                                            \
148         INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) |           \
149             (((int8_t)((b8)[0] ^ 0x80)) << 24))
150
151 #define _PCM_WRITE_U16_LE(b8, val)      do {                            \
152         *((uint16_t *)(b8)) = (val) ^ 0x8000;                           \
153 } while (0)
154 #define _PCM_WRITE_U32_LE(b8, val)      do {                            \
155         *((uint32_t *)(b8)) = (val) ^ 0x80000000;                       \
156 } while (0)
157 #define _PCM_WRITE_U16_BE(bb8, vval)    do {                            \
158         intpcm_t val = (vval);                                          \
159         uint8_t *b8 = (bb8);                                            \
160         b8[1] = val;                                                    \
161         b8[0] = (val >> 8) ^ 0x80;                                      \
162 } while (0)
163 #define _PCM_WRITE_U32_BE(bb8, vval)    do {                            \
164         intpcm_t val = (vval);                                          \
165         uint8_t *b8 = (bb8);                                            \
166         b8[3] = val;                                                    \
167         b8[2] = val >> 8;                                               \
168         b8[1] = val >> 16;                                              \
169         b8[0] = (val >> 24) ^ 0x80;                                     \
170 } while (0)
171
172 #define _PCM_READ_S16_NE(b8)    _PCM_READ_S16_LE(b8)
173 #define _PCM_READ_U16_NE(b8)    _PCM_READ_U16_LE(b8)
174 #define _PCM_READ_S32_NE(b8)    _PCM_READ_S32_LE(b8)
175 #define _PCM_READ_U32_NE(b8)    _PCM_READ_U32_LE(b8)
176 #define _PCM_WRITE_S16_NE(b6)   _PCM_WRITE_S16_LE(b8)
177 #define _PCM_WRITE_U16_NE(b6)   _PCM_WRITE_U16_LE(b8)
178 #define _PCM_WRITE_S32_NE(b6)   _PCM_WRITE_S32_LE(b8)
179 #define _PCM_WRITE_U32_NE(b6)   _PCM_WRITE_U32_LE(b8)
180 #else   /* !LITTLE_ENDIAN */
181 #define _PCM_READ_S16_LE(b8)                                            \
182         INTPCM_T((b8)[0] | (((int8_t)((b8)[1])) << 8))
183 #define _PCM_READ_S32_LE(b8)                                            \
184         INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) |           \
185             (((int8_t)((b8)[3])) << 24))
186 #define _PCM_READ_S16_BE(b8)            INTPCM_T(*((int16_t *)(b8)))
187 #define _PCM_READ_S32_BE(b8)            INTPCM_T(*((int32_t *)(b8)))
188
189 #define _PCM_WRITE_S16_LE(bb8, vval)    do {                            \
190         intpcm_t val = (vval);                                          \
191         uint8_t *b8 = (bb8);                                            \
192         b8[0] = val;                                                    \
193         b8[1] = val >> 8;                                               \
194 } while (0)
195 #define _PCM_WRITE_S32_LE(bb8, vval)    do {                            \
196         intpcm_t val = (vval);                                          \
197         uint8_t *b8 = (bb8);                                            \
198         b8[0] = val;                                                    \
199         b8[1] = val >> 8;                                               \
200         b8[2] = val >> 16;                                              \
201         b8[3] = val >> 24;                                              \
202 } while (0)
203 #define _PCM_WRITE_S16_BE(b8, val)      do {                            \
204         *((int16_t *)(b8)) = (val);                                     \
205 } while (0)
206 #define _PCM_WRITE_S32_BE(b8, val)      do {                            \
207         *((int32_t *)(b8)) = (val);                                     \
208 } while (0)
209
210 #define _PCM_READ_U16_LE(b8)                                            \
211         INTPCM_T((b8)[0] | (((int8_t)((b8)[1] ^ 0x80)) << 8))
212 #define _PCM_READ_U32_LE(b8)                                            \
213         INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) |           \
214             (((int8_t)((b8)[3] ^ 0x80)) << 24))
215 #define _PCM_READ_U16_BE(b8)                                            \
216         INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
217 #define _PCM_READ_U32_BE(b8)                                            \
218         INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
219
220 #define _PCM_WRITE_U16_LE(bb8, vval)    do {                            \
221         intpcm_t val = (vval);                                          \
222         uint8_t *b8 = (bb8);                                            \
223         b8[0] = val;                                                    \
224         b8[1] = (val >> 8) ^ 0x80;                                      \
225 } while (0)
226 #define _PCM_WRITE_U32_LE(bb8, vval)    do {                            \
227         intpcm_t val = (vval);                                          \
228         uint8_t *b8 = (bb8);                                            \
229         b8[0] = val;                                                    \
230         b8[1] = val >> 8;                                               \
231         b8[2] = val >> 16;                                              \
232         b8[3] = (val >> 24) ^ 0x80;                                     \
233 } while (0)
234 #define _PCM_WRITE_U16_BE(b8, val)      do {                            \
235         *((uint16_t *)(b8)) = (val) ^ 0x8000;                           \
236 } while (0)
237 #define _PCM_WRITE_U32_BE(b8, val)      do {                            \
238         *((uint32_t *)(b8)) = (val) ^ 0x80000000;                       \
239 } while (0)
240
241 #define _PCM_READ_S16_NE(b8)    _PCM_READ_S16_BE(b8)
242 #define _PCM_READ_U16_NE(b8)    _PCM_READ_U16_BE(b8)
243 #define _PCM_READ_S32_NE(b8)    _PCM_READ_S32_BE(b8)
244 #define _PCM_READ_U32_NE(b8)    _PCM_READ_U32_BE(b8)
245 #define _PCM_WRITE_S16_NE(b6)   _PCM_WRITE_S16_BE(b8)
246 #define _PCM_WRITE_U16_NE(b6)   _PCM_WRITE_U16_BE(b8)
247 #define _PCM_WRITE_S32_NE(b6)   _PCM_WRITE_S32_BE(b8)
248 #define _PCM_WRITE_U32_NE(b6)   _PCM_WRITE_U32_BE(b8)
249 #endif  /* LITTLE_ENDIAN */
250
251 #define _PCM_READ_S24_LE(b8)                                            \
252         INTPCM_T((b8)[0] | ((b8)[1] << 8) | (((int8_t)((b8)[2])) << 16))
253 #define _PCM_READ_S24_BE(b8)                                            \
254         INTPCM_T((b8)[2] | ((b8)[1] << 8) | (((int8_t)((b8)[0])) << 16))
255
256 #define _PCM_WRITE_S24_LE(bb8, vval)    do {                            \
257         intpcm_t val = (vval);                                          \
258         uint8_t *b8 = (bb8);                                            \
259         b8[0] = val;                                                    \
260         b8[1] = val >> 8;                                               \
261         b8[2] = val >> 16;                                              \
262 } while (0)
263 #define _PCM_WRITE_S24_BE(bb8, vval)    do {                            \
264         intpcm_t val = (vval);                                          \
265         uint8_t *b8 = (bb8);                                            \
266         b8[2] = val;                                                    \
267         b8[1] = val >> 8;                                               \
268         b8[0] = val >> 16;                                              \
269 } while (0)
270
271 #define _PCM_READ_U24_LE(b8)                                            \
272         INTPCM_T((b8)[0] | ((b8)[1] << 8) |                             \
273             (((int8_t)((b8)[2] ^ 0x80)) << 16))
274 #define _PCM_READ_U24_BE(b8)                                            \
275         INTPCM_T((b8)[2] | ((b8)[1] << 8) |                             \
276             (((int8_t)((b8)[0] ^ 0x80)) << 16))
277
278 #define _PCM_WRITE_U24_LE(bb8, vval)    do {                            \
279         intpcm_t val = (vval);                                          \
280         uint8_t *b8 = (bb8);                                            \
281         b8[0] = val;                                                    \
282         b8[1] = val >> 8;                                               \
283         b8[2] = (val >> 16) ^ 0x80;                                     \
284 } while (0)
285 #define _PCM_WRITE_U24_BE(bb8, vval)    do {                            \
286         intpcm_t val = (vval);                                          \
287         uint8_t *b8 = (bb8);                                            \
288         b8[2] = val;                                                    \
289         b8[1] = val >> 8;                                               \
290         b8[0] = (val >> 16) ^ 0x80;                                     \
291 } while (0)
292
293 #if BYTE_ORDER == LITTLE_ENDIAN
294 #define _PCM_READ_S24_NE(b8)    _PCM_READ_S24_LE(b8)
295 #define _PCM_READ_U24_NE(b8)    _PCM_READ_U24_LE(b8)
296 #define _PCM_WRITE_S24_NE(b6)   _PCM_WRITE_S24_LE(b8)
297 #define _PCM_WRITE_U24_NE(b6)   _PCM_WRITE_U24_LE(b8)
298 #else   /* !LITTLE_ENDIAN */
299 #define _PCM_READ_S24_NE(b8)    _PCM_READ_S24_BE(b8)
300 #define _PCM_READ_U24_NE(b8)    _PCM_READ_U24_BE(b8)
301 #define _PCM_WRITE_S24_NE(b6)   _PCM_WRITE_S24_BE(b8)
302 #define _PCM_WRITE_U24_NE(b6)   _PCM_WRITE_U24_BE(b8)
303 #endif  /* LITTLE_ENDIAN */
304 /*
305  * 8bit sample is pretty much useless since it doesn't provide
306  * sufficient dynamic range throughout our filtering process.
307  * For the sake of completeness, declare it anyway.
308  */
309 #define _PCM_READ_S8_NE(b8)             INTPCM_T(*((int8_t *)(b8)))
310 #define _PCM_READ_U8_NE(b8)                                             \
311         INTPCM_T((int8_t)(*((uint8_t *)(b8)) ^ 0x80))
312
313 #define _PCM_WRITE_S8_NE(b8, val)       do {                            \
314         *((int8_t *)(b8)) = (val);                                      \
315 } while (0)
316 #define _PCM_WRITE_U8_NE(b8, val)       do {                            \
317         *((uint8_t *)(b8)) = (val) ^ 0x80;                              \
318 } while (0)
319
320 /*
321  * Common macross. Use this instead of "_", unless we want
322  * the real sample value.
323  */
324
325 /* 8bit */
326 #define PCM_READ_S8_NE(b8)              _PCM_READ_S8_NE(b8)
327 #define PCM_READ_U8_NE(b8)              _PCM_READ_U8_NE(b8)
328 #define PCM_WRITE_S8_NE(b8, val)        _PCM_WRITE_S8_NE(b8, val)
329 #define PCM_WRITE_U8_NE(b8, val)        _PCM_WRITE_U8_NE(b8, val)
330
331 /* 16bit */
332 #define PCM_READ_S16_LE(b8)             _PCM_READ_S16_LE(b8)
333 #define PCM_READ_S16_BE(b8)             _PCM_READ_S16_BE(b8)
334 #define PCM_READ_U16_LE(b8)             _PCM_READ_U16_LE(b8)
335 #define PCM_READ_U16_BE(b8)             _PCM_READ_U16_BE(b8)
336
337 #define PCM_WRITE_S16_LE(b8, val)       _PCM_WRITE_S16_LE(b8, val)
338 #define PCM_WRITE_S16_BE(b8, val)       _PCM_WRITE_S16_BE(b8, val)
339 #define PCM_WRITE_U16_LE(b8, val)       _PCM_WRITE_U16_LE(b8, val)
340 #define PCM_WRITE_U16_BE(b8, val)       _PCM_WRITE_U16_BE(b8, val)
341
342 #define PCM_READ_S16_NE(b8)             _PCM_READ_S16_NE(b8)
343 #define PCM_READ_U16_NE(b8)             _PCM_READ_U16_NE(b8)
344 #define PCM_WRITE_S16_NE(b8)            _PCM_WRITE_S16_NE(b8)
345 #define PCM_WRITE_U16_NE(b8)            _PCM_WRITE_U16_NE(b8)
346
347 /* 24bit */
348 #define PCM_READ_S24_LE(b8)             _PCM_READ_S24_LE(b8)
349 #define PCM_READ_S24_BE(b8)             _PCM_READ_S24_BE(b8)
350 #define PCM_READ_U24_LE(b8)             _PCM_READ_U24_LE(b8)
351 #define PCM_READ_U24_BE(b8)             _PCM_READ_U24_BE(b8)
352
353 #define PCM_WRITE_S24_LE(b8, val)       _PCM_WRITE_S24_LE(b8, val)
354 #define PCM_WRITE_S24_BE(b8, val)       _PCM_WRITE_S24_BE(b8, val)
355 #define PCM_WRITE_U24_LE(b8, val)       _PCM_WRITE_U24_LE(b8, val)
356 #define PCM_WRITE_U24_BE(b8, val)       _PCM_WRITE_U24_BE(b8, val)
357
358 #define PCM_READ_S24_NE(b8)             _PCM_READ_S24_NE(b8)
359 #define PCM_READ_U24_NE(b8)             _PCM_READ_U24_NE(b8)
360 #define PCM_WRITE_S24_NE(b8)            _PCM_WRITE_S24_NE(b8)
361 #define PCM_WRITE_U24_NE(b8)            _PCM_WRITE_U24_NE(b8)
362
363 /* 32bit */
364 #ifdef SND_PCM_64
365 #define PCM_READ_S32_LE(b8)             _PCM_READ_S32_LE(b8)
366 #define PCM_READ_S32_BE(b8)             _PCM_READ_S32_BE(b8)
367 #define PCM_READ_U32_LE(b8)             _PCM_READ_U32_LE(b8)
368 #define PCM_READ_U32_BE(b8)             _PCM_READ_U32_BE(b8)
369
370 #define PCM_WRITE_S32_LE(b8, val)       _PCM_WRITE_S32_LE(b8, val)
371 #define PCM_WRITE_S32_BE(b8, val)       _PCM_WRITE_S32_BE(b8, val)
372 #define PCM_WRITE_U32_LE(b8, val)       _PCM_WRITE_U32_LE(b8, val)
373 #define PCM_WRITE_U32_BE(b8, val)       _PCM_WRITE_U32_BE(b8, val)
374
375 #define PCM_READ_S32_NE(b8)             _PCM_READ_S32_NE(b8)
376 #define PCM_READ_U32_NE(b8)             _PCM_READ_U32_NE(b8)
377 #define PCM_WRITE_S32_NE(b8)            _PCM_WRITE_S32_NE(b8)
378 #define PCM_WRITE_U32_NE(b8)            _PCM_WRITE_U32_NE(b8)
379 #else   /* !SND_PCM_64 */
380 /*
381  * 24bit integer ?!? This is quite unfortunate, eh? Get the fact straight:
382  * Dynamic range for:
383  *      1) Human =~ 140db
384  *      2) 16bit = 96db (close enough)
385  *      3) 24bit = 144db (perfect)
386  *      4) 32bit = 196db (way too much)
387  *      5) Bugs Bunny = Gazillion!@%$Erbzzztt-EINVAL db
388  * Since we're not Bugs Bunny ..uh..err.. avoiding 64bit arithmetic, 24bit
389  * is pretty much sufficient for our signed integer processing.
390  */
391 #define PCM_READ_S32_LE(b8)             (_PCM_READ_S32_LE(b8) >> PCM_FXSHIFT)
392 #define PCM_READ_S32_BE(b8)             (_PCM_READ_S32_BE(b8) >> PCM_FXSHIFT)
393 #define PCM_READ_U32_LE(b8)             (_PCM_READ_U32_LE(b8) >> PCM_FXSHIFT)
394 #define PCM_READ_U32_BE(b8)             (_PCM_READ_U32_BE(b8) >> PCM_FXSHIFT)
395
396 #define PCM_READ_S32_NE(b8)             (_PCM_READ_S32_NE(b8) >> PCM_FXSHIFT)
397 #define PCM_READ_U32_NE(b8)             (_PCM_READ_U32_NE(b8) >> PCM_FXSHIFT)
398
399 #define PCM_WRITE_S32_LE(b8, val)                                       \
400                         _PCM_WRITE_S32_LE(b8, (val) << PCM_FXSHIFT)
401 #define PCM_WRITE_S32_BE(b8, val)                                       \
402                         _PCM_WRITE_S32_BE(b8, (val) << PCM_FXSHIFT)
403 #define PCM_WRITE_U32_LE(b8, val)                                       \
404                         _PCM_WRITE_U32_LE(b8, (val) << PCM_FXSHIFT)
405 #define PCM_WRITE_U32_BE(b8, val)                                       \
406                         _PCM_WRITE_U32_BE(b8, (val) << PCM_FXSHIFT)
407
408 #define PCM_WRITE_S32_NE(b8, val)                                       \
409                         _PCM_WRITE_S32_NE(b8, (val) << PCM_FXSHIFT)
410 #define PCM_WRITE_U32_NE(b8, val)                                       \
411                         _PCM_WRITE_U32_NE(b8, (val) << PCM_FXSHIFT)
412 #endif  /* SND_PCM_64 */
413
414 #define PCM_CLAMP_S8(val)                                               \
415                         (((val) > PCM_S8_MAX) ? PCM_S8_MAX :            \
416                          (((val) < PCM_S8_MIN) ? PCM_S8_MIN : (val)))
417 #define PCM_CLAMP_S16(val)                                              \
418                         (((val) > PCM_S16_MAX) ? PCM_S16_MAX :          \
419                          (((val) < PCM_S16_MIN) ? PCM_S16_MIN : (val)))
420 #define PCM_CLAMP_S24(val)                                              \
421                         (((val) > PCM_S24_MAX) ? PCM_S24_MAX :          \
422                          (((val) < PCM_S24_MIN) ? PCM_S24_MIN : (val)))
423
424 #ifdef SND_PCM_64
425 #define PCM_CLAMP_S32(val)                                              \
426                         (((val) > PCM_S32_MAX) ? PCM_S32_MAX :          \
427                          (((val) < PCM_S32_MIN) ? PCM_S32_MIN : (val)))
428 #else   /* !SND_PCM_64 */
429 #define PCM_CLAMP_S32(val)                                              \
430                         (((val) > PCM_S24_MAX) ? PCM_S32_MAX :          \
431                          (((val) < PCM_S24_MIN) ? PCM_S32_MIN :         \
432                          ((val) << PCM_FXSHIFT)))
433 #endif  /* SND_PCM_64 */
434
435 #define PCM_CLAMP_U8(val)       PCM_CLAMP_S8(val)
436 #define PCM_CLAMP_U16(val)      PCM_CLAMP_S16(val)
437 #define PCM_CLAMP_U24(val)      PCM_CLAMP_S24(val)
438 #define PCM_CLAMP_U32(val)      PCM_CLAMP_S32(val)
439
440 #endif  /* !_SND_PCM_H_ */