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