1193640Sariff/*-
2193640Sariff * Copyright (c) 2006-2009 Ariff Abdullah <ariff@FreeBSD.org>
3193640Sariff * All rights reserved.
4193640Sariff *
5193640Sariff * Redistribution and use in source and binary forms, with or without
6193640Sariff * modification, are permitted provided that the following conditions
7193640Sariff * are met:
8193640Sariff * 1. Redistributions of source code must retain the above copyright
9193640Sariff *    notice, this list of conditions and the following disclaimer.
10193640Sariff * 2. Redistributions in binary form must reproduce the above copyright
11193640Sariff *    notice, this list of conditions and the following disclaimer in the
12193640Sariff *    documentation and/or other materials provided with the distribution.
13193640Sariff *
14193640Sariff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15193640Sariff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16193640Sariff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17193640Sariff * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18193640Sariff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19193640Sariff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20193640Sariff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21193640Sariff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22193640Sariff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23193640Sariff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24193640Sariff * SUCH DAMAGE.
25193640Sariff *
26193640Sariff * $FreeBSD: releng/10.2/sys/dev/sound/pcm/pcm.h 193640 2009-06-07 19:12:08Z ariff $
27193640Sariff */
28193640Sariff
29193640Sariff#ifndef _SND_PCM_H_
30193640Sariff#define _SND_PCM_H_
31193640Sariff
32193640Sariff#include <sys/param.h>
33193640Sariff
34193640Sariff/*
35193640Sariff * Macros for reading/writing PCM sample / int values from bytes array.
36193640Sariff * Since every process is done using signed integer (and to make our life
37193640Sariff * less miserable), unsigned sample will be converted to its signed
38193640Sariff * counterpart and restored during writing back. To avoid overflow,
39193640Sariff * we truncate 32bit (and only 32bit) samples down to 24bit (see below
40193640Sariff * for the reason), unless SND_PCM_64 is defined.
41193640Sariff */
42193640Sariff
43193640Sariff/*
44193640Sariff * Automatically turn on 64bit arithmetic on suitable archs
45193640Sariff * (amd64 64bit, ia64, etc..) for wider 32bit samples / integer processing.
46193640Sariff */
47193640Sariff#if LONG_BIT >= 64
48193640Sariff#undef SND_PCM_64
49193640Sariff#define SND_PCM_64	1
50193640Sariff#endif
51193640Sariff
52193640Sarifftypedef int32_t intpcm_t;
53193640Sariff
54193640Sarifftypedef int32_t intpcm8_t;
55193640Sarifftypedef int32_t intpcm16_t;
56193640Sarifftypedef int32_t intpcm24_t;
57193640Sariff
58193640Sarifftypedef uint32_t uintpcm_t;
59193640Sariff
60193640Sarifftypedef uint32_t uintpcm8_t;
61193640Sarifftypedef uint32_t uintpcm16_t;
62193640Sarifftypedef uint32_t uintpcm24_t;
63193640Sariff
64193640Sariff#ifdef SND_PCM_64
65193640Sarifftypedef int64_t  intpcm32_t;
66193640Sarifftypedef uint64_t uintpcm32_t;
67193640Sariff#else
68193640Sarifftypedef int32_t  intpcm32_t;
69193640Sarifftypedef uint32_t uintpcm32_t;
70193640Sariff#endif
71193640Sariff
72193640Sarifftypedef int64_t intpcm64_t;
73193640Sarifftypedef uint64_t uintpcm64_t;
74193640Sariff
75193640Sariff/* 32bit fixed point shift */
76193640Sariff#define	PCM_FXSHIFT	8
77193640Sariff
78193640Sariff#define PCM_S8_MAX	  0x7f
79193640Sariff#define PCM_S8_MIN	 -0x80
80193640Sariff#define PCM_S16_MAX	  0x7fff
81193640Sariff#define PCM_S16_MIN	 -0x8000
82193640Sariff#define PCM_S24_MAX	  0x7fffff
83193640Sariff#define PCM_S24_MIN	 -0x800000
84193640Sariff#ifdef SND_PCM_64
85193640Sariff#if LONG_BIT >= 64
86193640Sariff#define PCM_S32_MAX	  0x7fffffffL
87193640Sariff#define PCM_S32_MIN	 -0x80000000L
88193640Sariff#else
89193640Sariff#define PCM_S32_MAX	  0x7fffffffLL
90193640Sariff#define PCM_S32_MIN	 -0x80000000LL
91193640Sariff#endif
92193640Sariff#else
93193640Sariff#define PCM_S32_MAX	  0x7fffffff
94193640Sariff#define PCM_S32_MIN	(-0x7fffffff - 1)
95193640Sariff#endif
96193640Sariff
97193640Sariff/* Bytes-per-sample definition */
98193640Sariff#define PCM_8_BPS	1
99193640Sariff#define PCM_16_BPS	2
100193640Sariff#define PCM_24_BPS	3
101193640Sariff#define PCM_32_BPS	4
102193640Sariff
103193640Sariff#define INTPCM_T(v)	((intpcm_t)(v))
104193640Sariff#define INTPCM8_T(v)	((intpcm8_t)(v))
105193640Sariff#define INTPCM16_T(v)	((intpcm16_t)(v))
106193640Sariff#define INTPCM24_T(v)	((intpcm24_t)(v))
107193640Sariff#define INTPCM32_T(v)	((intpcm32_t)(v))
108193640Sariff
109193640Sariff#if BYTE_ORDER == LITTLE_ENDIAN
110193640Sariff#define _PCM_READ_S16_LE(b8)		INTPCM_T(*((int16_t *)(b8)))
111193640Sariff#define _PCM_READ_S32_LE(b8)		INTPCM_T(*((int32_t *)(b8)))
112193640Sariff#define _PCM_READ_S16_BE(b8)						\
113193640Sariff	INTPCM_T((b8)[1] | (((int8_t)((b8)[0])) << 8))
114193640Sariff#define _PCM_READ_S32_BE(b8)						\
115193640Sariff	INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) |		\
116193640Sariff	    (((int8_t)((b8)[0])) << 24))
117193640Sariff
118193640Sariff#define _PCM_WRITE_S16_LE(b8, val)	do {				\
119193640Sariff	*((int16_t *)(b8)) = (val);					\
120193640Sariff} while (0)
121193640Sariff#define _PCM_WRITE_S32_LE(b8, val)	do {				\
122193640Sariff	*((int32_t *)(b8)) = (val);					\
123193640Sariff} while (0)
124193640Sariff#define _PCM_WRITE_S16_BE(bb8, vval)	do {				\
125193640Sariff	intpcm_t val = (vval); 						\
126193640Sariff	uint8_t *b8 = (bb8);						\
127193640Sariff	b8[1] = val;							\
128193640Sariff	b8[0] = val >> 8;						\
129193640Sariff} while (0)
130193640Sariff#define _PCM_WRITE_S32_BE(bb8, vval)	do {				\
131193640Sariff	intpcm_t val = (vval);						\
132193640Sariff	uint8_t *b8 = (bb8);						\
133193640Sariff	b8[3] = val;							\
134193640Sariff	b8[2] = val >> 8;						\
135193640Sariff	b8[1] = val >> 16;						\
136193640Sariff	b8[0] = val >> 24;						\
137193640Sariff} while (0)
138193640Sariff
139193640Sariff#define _PCM_READ_U16_LE(b8)						\
140193640Sariff	INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
141193640Sariff#define _PCM_READ_U32_LE(b8)						\
142193640Sariff	INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
143193640Sariff#define _PCM_READ_U16_BE(b8)						\
144193640Sariff	INTPCM_T((b8)[1] | (((int8_t)((b8)[0] ^ 0x80)) << 8))
145193640Sariff#define _PCM_READ_U32_BE(b8)						\
146193640Sariff	INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) |		\
147193640Sariff	    (((int8_t)((b8)[0] ^ 0x80)) << 24))
148193640Sariff
149193640Sariff#define _PCM_WRITE_U16_LE(b8, val)	do {				\
150193640Sariff	*((uint16_t *)(b8)) = (val) ^ 0x8000;				\
151193640Sariff} while (0)
152193640Sariff#define _PCM_WRITE_U32_LE(b8, val)	do {				\
153193640Sariff	*((uint32_t *)(b8)) = (val) ^ 0x80000000;			\
154193640Sariff} while (0)
155193640Sariff#define _PCM_WRITE_U16_BE(bb8, vval)	do {				\
156193640Sariff	intpcm_t val = (vval);						\
157193640Sariff	uint8_t *b8 = (bb8);						\
158193640Sariff	b8[1] = val;							\
159193640Sariff	b8[0] = (val >> 8) ^ 0x80;					\
160193640Sariff} while (0)
161193640Sariff#define _PCM_WRITE_U32_BE(bb8, vval)	do {				\
162193640Sariff	intpcm_t val = (vval);						\
163193640Sariff	uint8_t *b8 = (bb8);						\
164193640Sariff	b8[3] = val;							\
165193640Sariff	b8[2] = val >> 8;						\
166193640Sariff	b8[1] = val >> 16;						\
167193640Sariff	b8[0] = (val >> 24) ^ 0x80;					\
168193640Sariff} while (0)
169193640Sariff
170193640Sariff#define _PCM_READ_S16_NE(b8)	_PCM_READ_S16_LE(b8)
171193640Sariff#define _PCM_READ_U16_NE(b8)	_PCM_READ_U16_LE(b8)
172193640Sariff#define _PCM_READ_S32_NE(b8)	_PCM_READ_S32_LE(b8)
173193640Sariff#define _PCM_READ_U32_NE(b8)	_PCM_READ_U32_LE(b8)
174193640Sariff#define _PCM_WRITE_S16_NE(b6)	_PCM_WRITE_S16_LE(b8)
175193640Sariff#define _PCM_WRITE_U16_NE(b6)	_PCM_WRITE_U16_LE(b8)
176193640Sariff#define _PCM_WRITE_S32_NE(b6)	_PCM_WRITE_S32_LE(b8)
177193640Sariff#define _PCM_WRITE_U32_NE(b6)	_PCM_WRITE_U32_LE(b8)
178193640Sariff#else	/* !LITTLE_ENDIAN */
179193640Sariff#define _PCM_READ_S16_LE(b8)						\
180193640Sariff	INTPCM_T((b8)[0] | (((int8_t)((b8)[1])) << 8))
181193640Sariff#define _PCM_READ_S32_LE(b8)						\
182193640Sariff	INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) |		\
183193640Sariff	    (((int8_t)((b8)[3])) << 24))
184193640Sariff#define _PCM_READ_S16_BE(b8)		INTPCM_T(*((int16_t *)(b8)))
185193640Sariff#define _PCM_READ_S32_BE(b8)		INTPCM_T(*((int32_t *)(b8)))
186193640Sariff
187193640Sariff#define _PCM_WRITE_S16_LE(bb8, vval)	do {				\
188193640Sariff	intpcm_t val = (vval);						\
189193640Sariff	uint8_t *b8 = (bb8);						\
190193640Sariff	b8[0] = val;							\
191193640Sariff	b8[1] = val >> 8;						\
192193640Sariff} while (0)
193193640Sariff#define _PCM_WRITE_S32_LE(bb8, vval)	do {				\
194193640Sariff	intpcm_t val = (vval);						\
195193640Sariff	uint8_t *b8 = (bb8);						\
196193640Sariff	b8[0] = val;							\
197193640Sariff	b8[1] = val >> 8;						\
198193640Sariff	b8[2] = val >> 16;						\
199193640Sariff	b8[3] = val >> 24;						\
200193640Sariff} while (0)
201193640Sariff#define _PCM_WRITE_S16_BE(b8, val)	do {				\
202193640Sariff	*((int16_t *)(b8)) = (val);					\
203193640Sariff} while (0)
204193640Sariff#define _PCM_WRITE_S32_BE(b8, val)	do {				\
205193640Sariff	*((int32_t *)(b8)) = (val);					\
206193640Sariff} while (0)
207193640Sariff
208193640Sariff#define _PCM_READ_U16_LE(b8)						\
209193640Sariff	INTPCM_T((b8)[0] | (((int8_t)((b8)[1] ^ 0x80)) << 8))
210193640Sariff#define _PCM_READ_U32_LE(b8)						\
211193640Sariff	INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) |		\
212193640Sariff	    (((int8_t)((b8)[3] ^ 0x80)) << 24))
213193640Sariff#define _PCM_READ_U16_BE(b8)						\
214193640Sariff	INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
215193640Sariff#define _PCM_READ_U32_BE(b8)						\
216193640Sariff	INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
217193640Sariff
218193640Sariff#define _PCM_WRITE_U16_LE(bb8, vval)	do {				\
219193640Sariff	intpcm_t val = (vval);						\
220193640Sariff	uint8_t *b8 = (bb8);						\
221193640Sariff	b8[0] = val;							\
222193640Sariff	b8[1] = (val >> 8) ^ 0x80;					\
223193640Sariff} while (0)
224193640Sariff#define _PCM_WRITE_U32_LE(bb8, vval)	do {				\
225193640Sariff	intpcm_t val = (vval);						\
226193640Sariff	uint8_t *b8 = (bb8);						\
227193640Sariff	b8[0] = val;							\
228193640Sariff	b8[1] = val >> 8;						\
229193640Sariff	b8[2] = val >> 16;						\
230193640Sariff	b8[3] = (val >> 24) ^ 0x80;					\
231193640Sariff} while (0)
232193640Sariff#define _PCM_WRITE_U16_BE(b8, val)	do {				\
233193640Sariff	*((uint16_t *)(b8)) = (val) ^ 0x8000;				\
234193640Sariff} while (0)
235193640Sariff#define _PCM_WRITE_U32_BE(b8, val)	do {				\
236193640Sariff	*((uint32_t *)(b8)) = (val) ^ 0x80000000;			\
237193640Sariff} while (0)
238193640Sariff
239193640Sariff#define _PCM_READ_S16_NE(b8)	_PCM_READ_S16_BE(b8)
240193640Sariff#define _PCM_READ_U16_NE(b8)	_PCM_READ_U16_BE(b8)
241193640Sariff#define _PCM_READ_S32_NE(b8)	_PCM_READ_S32_BE(b8)
242193640Sariff#define _PCM_READ_U32_NE(b8)	_PCM_READ_U32_BE(b8)
243193640Sariff#define _PCM_WRITE_S16_NE(b6)	_PCM_WRITE_S16_BE(b8)
244193640Sariff#define _PCM_WRITE_U16_NE(b6)	_PCM_WRITE_U16_BE(b8)
245193640Sariff#define _PCM_WRITE_S32_NE(b6)	_PCM_WRITE_S32_BE(b8)
246193640Sariff#define _PCM_WRITE_U32_NE(b6)	_PCM_WRITE_U32_BE(b8)
247193640Sariff#endif	/* LITTLE_ENDIAN */
248193640Sariff
249193640Sariff#define _PCM_READ_S24_LE(b8)						\
250193640Sariff	INTPCM_T((b8)[0] | ((b8)[1] << 8) | (((int8_t)((b8)[2])) << 16))
251193640Sariff#define _PCM_READ_S24_BE(b8)						\
252193640Sariff	INTPCM_T((b8)[2] | ((b8)[1] << 8) | (((int8_t)((b8)[0])) << 16))
253193640Sariff
254193640Sariff#define _PCM_WRITE_S24_LE(bb8, vval)	do {				\
255193640Sariff	intpcm_t val = (vval);						\
256193640Sariff	uint8_t *b8 = (bb8);						\
257193640Sariff	b8[0] = val;							\
258193640Sariff	b8[1] = val >> 8;						\
259193640Sariff	b8[2] = val >> 16;						\
260193640Sariff} while (0)
261193640Sariff#define _PCM_WRITE_S24_BE(bb8, vval)	do {				\
262193640Sariff	intpcm_t val = (vval);						\
263193640Sariff	uint8_t *b8 = (bb8);						\
264193640Sariff	b8[2] = val;							\
265193640Sariff	b8[1] = val >> 8;						\
266193640Sariff	b8[0] = val >> 16;						\
267193640Sariff} while (0)
268193640Sariff
269193640Sariff#define _PCM_READ_U24_LE(b8)						\
270193640Sariff	INTPCM_T((b8)[0] | ((b8)[1] << 8) |				\
271193640Sariff	    (((int8_t)((b8)[2] ^ 0x80)) << 16))
272193640Sariff#define _PCM_READ_U24_BE(b8)						\
273193640Sariff	INTPCM_T((b8)[2] | ((b8)[1] << 8) |				\
274193640Sariff	    (((int8_t)((b8)[0] ^ 0x80)) << 16))
275193640Sariff
276193640Sariff#define _PCM_WRITE_U24_LE(bb8, vval)	do {				\
277193640Sariff	intpcm_t val = (vval);						\
278193640Sariff	uint8_t *b8 = (bb8);						\
279193640Sariff	b8[0] = val;							\
280193640Sariff	b8[1] = val >> 8;						\
281193640Sariff	b8[2] = (val >> 16) ^ 0x80;					\
282193640Sariff} while (0)
283193640Sariff#define _PCM_WRITE_U24_BE(bb8, vval)	do {				\
284193640Sariff	intpcm_t val = (vval);						\
285193640Sariff	uint8_t *b8 = (bb8);						\
286193640Sariff	b8[2] = val;							\
287193640Sariff	b8[1] = val >> 8;						\
288193640Sariff	b8[0] = (val >> 16) ^ 0x80;					\
289193640Sariff} while (0)
290193640Sariff
291193640Sariff#if BYTE_ORDER == LITTLE_ENDIAN
292193640Sariff#define _PCM_READ_S24_NE(b8)	_PCM_READ_S24_LE(b8)
293193640Sariff#define _PCM_READ_U24_NE(b8)	_PCM_READ_U24_LE(b8)
294193640Sariff#define _PCM_WRITE_S24_NE(b6)	_PCM_WRITE_S24_LE(b8)
295193640Sariff#define _PCM_WRITE_U24_NE(b6)	_PCM_WRITE_U24_LE(b8)
296193640Sariff#else	/* !LITTLE_ENDIAN */
297193640Sariff#define _PCM_READ_S24_NE(b8)	_PCM_READ_S24_BE(b8)
298193640Sariff#define _PCM_READ_U24_NE(b8)	_PCM_READ_U24_BE(b8)
299193640Sariff#define _PCM_WRITE_S24_NE(b6)	_PCM_WRITE_S24_BE(b8)
300193640Sariff#define _PCM_WRITE_U24_NE(b6)	_PCM_WRITE_U24_BE(b8)
301193640Sariff#endif	/* LITTLE_ENDIAN */
302193640Sariff/*
303193640Sariff * 8bit sample is pretty much useless since it doesn't provide
304193640Sariff * sufficient dynamic range throughout our filtering process.
305193640Sariff * For the sake of completeness, declare it anyway.
306193640Sariff */
307193640Sariff#define _PCM_READ_S8_NE(b8)		INTPCM_T(*((int8_t *)(b8)))
308193640Sariff#define _PCM_READ_U8_NE(b8)						\
309193640Sariff	INTPCM_T((int8_t)(*((uint8_t *)(b8)) ^ 0x80))
310193640Sariff
311193640Sariff#define _PCM_WRITE_S8_NE(b8, val)	do {				\
312193640Sariff	*((int8_t *)(b8)) = (val);					\
313193640Sariff} while (0)
314193640Sariff#define _PCM_WRITE_U8_NE(b8, val)	do {				\
315193640Sariff	*((uint8_t *)(b8)) = (val) ^ 0x80;				\
316193640Sariff} while (0)
317193640Sariff
318193640Sariff/*
319193640Sariff * Common macross. Use this instead of "_", unless we want
320193640Sariff * the real sample value.
321193640Sariff */
322193640Sariff
323193640Sariff/* 8bit */
324193640Sariff#define PCM_READ_S8_NE(b8)		_PCM_READ_S8_NE(b8)
325193640Sariff#define PCM_READ_U8_NE(b8)		_PCM_READ_U8_NE(b8)
326193640Sariff#define PCM_WRITE_S8_NE(b8, val)	_PCM_WRITE_S8_NE(b8, val)
327193640Sariff#define PCM_WRITE_U8_NE(b8, val)	_PCM_WRITE_U8_NE(b8, val)
328193640Sariff
329193640Sariff/* 16bit */
330193640Sariff#define PCM_READ_S16_LE(b8)		_PCM_READ_S16_LE(b8)
331193640Sariff#define PCM_READ_S16_BE(b8)		_PCM_READ_S16_BE(b8)
332193640Sariff#define PCM_READ_U16_LE(b8)		_PCM_READ_U16_LE(b8)
333193640Sariff#define PCM_READ_U16_BE(b8)		_PCM_READ_U16_BE(b8)
334193640Sariff
335193640Sariff#define PCM_WRITE_S16_LE(b8, val)	_PCM_WRITE_S16_LE(b8, val)
336193640Sariff#define PCM_WRITE_S16_BE(b8, val)	_PCM_WRITE_S16_BE(b8, val)
337193640Sariff#define PCM_WRITE_U16_LE(b8, val)	_PCM_WRITE_U16_LE(b8, val)
338193640Sariff#define PCM_WRITE_U16_BE(b8, val)	_PCM_WRITE_U16_BE(b8, val)
339193640Sariff
340193640Sariff#define PCM_READ_S16_NE(b8)		_PCM_READ_S16_NE(b8)
341193640Sariff#define PCM_READ_U16_NE(b8)		_PCM_READ_U16_NE(b8)
342193640Sariff#define PCM_WRITE_S16_NE(b8)		_PCM_WRITE_S16_NE(b8)
343193640Sariff#define PCM_WRITE_U16_NE(b8)		_PCM_WRITE_U16_NE(b8)
344193640Sariff
345193640Sariff/* 24bit */
346193640Sariff#define PCM_READ_S24_LE(b8)		_PCM_READ_S24_LE(b8)
347193640Sariff#define PCM_READ_S24_BE(b8)		_PCM_READ_S24_BE(b8)
348193640Sariff#define PCM_READ_U24_LE(b8)		_PCM_READ_U24_LE(b8)
349193640Sariff#define PCM_READ_U24_BE(b8)		_PCM_READ_U24_BE(b8)
350193640Sariff
351193640Sariff#define PCM_WRITE_S24_LE(b8, val)	_PCM_WRITE_S24_LE(b8, val)
352193640Sariff#define PCM_WRITE_S24_BE(b8, val)	_PCM_WRITE_S24_BE(b8, val)
353193640Sariff#define PCM_WRITE_U24_LE(b8, val)	_PCM_WRITE_U24_LE(b8, val)
354193640Sariff#define PCM_WRITE_U24_BE(b8, val)	_PCM_WRITE_U24_BE(b8, val)
355193640Sariff
356193640Sariff#define PCM_READ_S24_NE(b8)		_PCM_READ_S24_NE(b8)
357193640Sariff#define PCM_READ_U24_NE(b8)		_PCM_READ_U24_NE(b8)
358193640Sariff#define PCM_WRITE_S24_NE(b8)		_PCM_WRITE_S24_NE(b8)
359193640Sariff#define PCM_WRITE_U24_NE(b8)		_PCM_WRITE_U24_NE(b8)
360193640Sariff
361193640Sariff/* 32bit */
362193640Sariff#ifdef SND_PCM_64
363193640Sariff#define PCM_READ_S32_LE(b8)		_PCM_READ_S32_LE(b8)
364193640Sariff#define PCM_READ_S32_BE(b8)		_PCM_READ_S32_BE(b8)
365193640Sariff#define PCM_READ_U32_LE(b8)		_PCM_READ_U32_LE(b8)
366193640Sariff#define PCM_READ_U32_BE(b8)		_PCM_READ_U32_BE(b8)
367193640Sariff
368193640Sariff#define PCM_WRITE_S32_LE(b8, val)	_PCM_WRITE_S32_LE(b8, val)
369193640Sariff#define PCM_WRITE_S32_BE(b8, val)	_PCM_WRITE_S32_BE(b8, val)
370193640Sariff#define PCM_WRITE_U32_LE(b8, val)	_PCM_WRITE_U32_LE(b8, val)
371193640Sariff#define PCM_WRITE_U32_BE(b8, val)	_PCM_WRITE_U32_BE(b8, val)
372193640Sariff
373193640Sariff#define PCM_READ_S32_NE(b8)		_PCM_READ_S32_NE(b8)
374193640Sariff#define PCM_READ_U32_NE(b8)		_PCM_READ_U32_NE(b8)
375193640Sariff#define PCM_WRITE_S32_NE(b8)		_PCM_WRITE_S32_NE(b8)
376193640Sariff#define PCM_WRITE_U32_NE(b8)		_PCM_WRITE_U32_NE(b8)
377193640Sariff#else	/* !SND_PCM_64 */
378193640Sariff/*
379193640Sariff * 24bit integer ?!? This is quite unfortunate, eh? Get the fact straight:
380193640Sariff * Dynamic range for:
381193640Sariff *	1) Human =~ 140db
382193640Sariff *	2) 16bit = 96db (close enough)
383193640Sariff *	3) 24bit = 144db (perfect)
384193640Sariff *	4) 32bit = 196db (way too much)
385193640Sariff *	5) Bugs Bunny = Gazillion!@%$Erbzzztt-EINVAL db
386193640Sariff * Since we're not Bugs Bunny ..uh..err.. avoiding 64bit arithmetic, 24bit
387193640Sariff * is pretty much sufficient for our signed integer processing.
388193640Sariff */
389193640Sariff#define PCM_READ_S32_LE(b8)		(_PCM_READ_S32_LE(b8) >> PCM_FXSHIFT)
390193640Sariff#define PCM_READ_S32_BE(b8)		(_PCM_READ_S32_BE(b8) >> PCM_FXSHIFT)
391193640Sariff#define PCM_READ_U32_LE(b8)		(_PCM_READ_U32_LE(b8) >> PCM_FXSHIFT)
392193640Sariff#define PCM_READ_U32_BE(b8)		(_PCM_READ_U32_BE(b8) >> PCM_FXSHIFT)
393193640Sariff
394193640Sariff#define PCM_READ_S32_NE(b8)		(_PCM_READ_S32_NE(b8) >> PCM_FXSHIFT)
395193640Sariff#define PCM_READ_U32_NE(b8)		(_PCM_READ_U32_NE(b8) >> PCM_FXSHIFT)
396193640Sariff
397193640Sariff#define PCM_WRITE_S32_LE(b8, val)					\
398193640Sariff			_PCM_WRITE_S32_LE(b8, (val) << PCM_FXSHIFT)
399193640Sariff#define PCM_WRITE_S32_BE(b8, val)					\
400193640Sariff			_PCM_WRITE_S32_BE(b8, (val) << PCM_FXSHIFT)
401193640Sariff#define PCM_WRITE_U32_LE(b8, val)					\
402193640Sariff			_PCM_WRITE_U32_LE(b8, (val) << PCM_FXSHIFT)
403193640Sariff#define PCM_WRITE_U32_BE(b8, val)					\
404193640Sariff			_PCM_WRITE_U32_BE(b8, (val) << PCM_FXSHIFT)
405193640Sariff
406193640Sariff#define PCM_WRITE_S32_NE(b8, val)					\
407193640Sariff			_PCM_WRITE_S32_NE(b8, (val) << PCM_FXSHIFT)
408193640Sariff#define PCM_WRITE_U32_NE(b8, val)					\
409193640Sariff			_PCM_WRITE_U32_NE(b8, (val) << PCM_FXSHIFT)
410193640Sariff#endif	/* SND_PCM_64 */
411193640Sariff
412193640Sariff#define PCM_CLAMP_S8(val)						\
413193640Sariff			(((val) > PCM_S8_MAX) ? PCM_S8_MAX :		\
414193640Sariff			 (((val) < PCM_S8_MIN) ? PCM_S8_MIN : (val)))
415193640Sariff#define PCM_CLAMP_S16(val)						\
416193640Sariff			(((val) > PCM_S16_MAX) ? PCM_S16_MAX :		\
417193640Sariff			 (((val) < PCM_S16_MIN) ? PCM_S16_MIN : (val)))
418193640Sariff#define PCM_CLAMP_S24(val)						\
419193640Sariff			(((val) > PCM_S24_MAX) ? PCM_S24_MAX :		\
420193640Sariff			 (((val) < PCM_S24_MIN) ? PCM_S24_MIN : (val)))
421193640Sariff
422193640Sariff#ifdef SND_PCM_64
423193640Sariff#define PCM_CLAMP_S32(val)						\
424193640Sariff			(((val) > PCM_S32_MAX) ? PCM_S32_MAX :		\
425193640Sariff			 (((val) < PCM_S32_MIN) ? PCM_S32_MIN : (val)))
426193640Sariff#else	/* !SND_PCM_64 */
427193640Sariff#define PCM_CLAMP_S32(val)						\
428193640Sariff			(((val) > PCM_S24_MAX) ? PCM_S32_MAX :		\
429193640Sariff			 (((val) < PCM_S24_MIN) ? PCM_S32_MIN :		\
430193640Sariff			 ((val) << PCM_FXSHIFT)))
431193640Sariff#endif	/* SND_PCM_64 */
432193640Sariff
433193640Sariff#define PCM_CLAMP_U8(val)	PCM_CLAMP_S8(val)
434193640Sariff#define PCM_CLAMP_U16(val)	PCM_CLAMP_S16(val)
435193640Sariff#define PCM_CLAMP_U24(val)	PCM_CLAMP_S24(val)
436193640Sariff#define PCM_CLAMP_U32(val)	PCM_CLAMP_S32(val)
437193640Sariff
438193640Sariff#endif	/* !_SND_PCM_H_ */
439