#ifndef _SND_PCM_H_
#define _SND_PCM_H_
#include <sys/param.h>
#if LONG_BIT >= 64
#undef SND_PCM_64
#define SND_PCM_64 1
#endif
typedef int32_t intpcm_t;
typedef int32_t intpcm8_t;
typedef int32_t intpcm16_t;
typedef int32_t intpcm24_t;
typedef uint32_t uintpcm_t;
typedef uint32_t uintpcm8_t;
typedef uint32_t uintpcm16_t;
typedef uint32_t uintpcm24_t;
#ifdef SND_PCM_64
typedef int64_t intpcm32_t;
typedef uint64_t uintpcm32_t;
#else
typedef int32_t intpcm32_t;
typedef uint32_t uintpcm32_t;
#endif
typedef int64_t intpcm64_t;
typedef uint64_t uintpcm64_t;
#define PCM_FXSHIFT 8
#define PCM_S8_MAX 0x7f
#define PCM_S8_MIN -0x80
#define PCM_S16_MAX 0x7fff
#define PCM_S16_MIN -0x8000
#define PCM_S24_MAX 0x7fffff
#define PCM_S24_MIN -0x800000
#ifdef SND_PCM_64
#if LONG_BIT >= 64
#define PCM_S32_MAX 0x7fffffffL
#define PCM_S32_MIN -0x80000000L
#else
#define PCM_S32_MAX 0x7fffffffLL
#define PCM_S32_MIN -0x80000000LL
#endif
#else
#define PCM_S32_MAX 0x7fffffff
#define PCM_S32_MIN (-0x7fffffff - 1)
#endif
#define PCM_8_BPS 1
#define PCM_16_BPS 2
#define PCM_24_BPS 3
#define PCM_32_BPS 4
#define INTPCM_T(v) ((intpcm_t)(v))
#define INTPCM8_T(v) ((intpcm8_t)(v))
#define INTPCM16_T(v) ((intpcm16_t)(v))
#define INTPCM24_T(v) ((intpcm24_t)(v))
#define INTPCM32_T(v) ((intpcm32_t)(v))
#if BYTE_ORDER == LITTLE_ENDIAN
#define _PCM_READ_S16_LE(b8) INTPCM_T(*((int16_t *)(b8)))
#define _PCM_READ_S32_LE(b8) INTPCM_T(*((int32_t *)(b8)))
#define _PCM_READ_S16_BE(b8) \
INTPCM_T((b8)[1] | (((int8_t)((b8)[0])) << 8))
#define _PCM_READ_S32_BE(b8) \
INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) | \
(((int8_t)((b8)[0])) << 24))
#define _PCM_WRITE_S16_LE(b8, val) do { \
*((int16_t *)(b8)) = (val); \
} while (0)
#define _PCM_WRITE_S32_LE(b8, val) do { \
*((int32_t *)(b8)) = (val); \
} while (0)
#define _PCM_WRITE_S16_BE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[1] = val; \
b8[0] = val >> 8; \
} while (0)
#define _PCM_WRITE_S32_BE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[3] = val; \
b8[2] = val >> 8; \
b8[1] = val >> 16; \
b8[0] = val >> 24; \
} while (0)
#define _PCM_READ_U16_LE(b8) \
INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
#define _PCM_READ_U32_LE(b8) \
INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
#define _PCM_READ_U16_BE(b8) \
INTPCM_T((b8)[1] | (((int8_t)((b8)[0] ^ 0x80)) << 8))
#define _PCM_READ_U32_BE(b8) \
INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) | \
(((int8_t)((b8)[0] ^ 0x80)) << 24))
#define _PCM_WRITE_U16_LE(b8, val) do { \
*((uint16_t *)(b8)) = (val) ^ 0x8000; \
} while (0)
#define _PCM_WRITE_U32_LE(b8, val) do { \
*((uint32_t *)(b8)) = (val) ^ 0x80000000; \
} while (0)
#define _PCM_WRITE_U16_BE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[1] = val; \
b8[0] = (val >> 8) ^ 0x80; \
} while (0)
#define _PCM_WRITE_U32_BE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[3] = val; \
b8[2] = val >> 8; \
b8[1] = val >> 16; \
b8[0] = (val >> 24) ^ 0x80; \
} while (0)
#define _PCM_READ_S16_NE(b8) _PCM_READ_S16_LE(b8)
#define _PCM_READ_U16_NE(b8) _PCM_READ_U16_LE(b8)
#define _PCM_READ_S32_NE(b8) _PCM_READ_S32_LE(b8)
#define _PCM_READ_U32_NE(b8) _PCM_READ_U32_LE(b8)
#define _PCM_WRITE_S16_NE(b6) _PCM_WRITE_S16_LE(b8)
#define _PCM_WRITE_U16_NE(b6) _PCM_WRITE_U16_LE(b8)
#define _PCM_WRITE_S32_NE(b6) _PCM_WRITE_S32_LE(b8)
#define _PCM_WRITE_U32_NE(b6) _PCM_WRITE_U32_LE(b8)
#else
#define _PCM_READ_S16_LE(b8) \
INTPCM_T((b8)[0] | (((int8_t)((b8)[1])) << 8))
#define _PCM_READ_S32_LE(b8) \
INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) | \
(((int8_t)((b8)[3])) << 24))
#define _PCM_READ_S16_BE(b8) INTPCM_T(*((int16_t *)(b8)))
#define _PCM_READ_S32_BE(b8) INTPCM_T(*((int32_t *)(b8)))
#define _PCM_WRITE_S16_LE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[0] = val; \
b8[1] = val >> 8; \
} while (0)
#define _PCM_WRITE_S32_LE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[0] = val; \
b8[1] = val >> 8; \
b8[2] = val >> 16; \
b8[3] = val >> 24; \
} while (0)
#define _PCM_WRITE_S16_BE(b8, val) do { \
*((int16_t *)(b8)) = (val); \
} while (0)
#define _PCM_WRITE_S32_BE(b8, val) do { \
*((int32_t *)(b8)) = (val); \
} while (0)
#define _PCM_READ_U16_LE(b8) \
INTPCM_T((b8)[0] | (((int8_t)((b8)[1] ^ 0x80)) << 8))
#define _PCM_READ_U32_LE(b8) \
INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) | \
(((int8_t)((b8)[3] ^ 0x80)) << 24))
#define _PCM_READ_U16_BE(b8) \
INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
#define _PCM_READ_U32_BE(b8) \
INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
#define _PCM_WRITE_U16_LE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[0] = val; \
b8[1] = (val >> 8) ^ 0x80; \
} while (0)
#define _PCM_WRITE_U32_LE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[0] = val; \
b8[1] = val >> 8; \
b8[2] = val >> 16; \
b8[3] = (val >> 24) ^ 0x80; \
} while (0)
#define _PCM_WRITE_U16_BE(b8, val) do { \
*((uint16_t *)(b8)) = (val) ^ 0x8000; \
} while (0)
#define _PCM_WRITE_U32_BE(b8, val) do { \
*((uint32_t *)(b8)) = (val) ^ 0x80000000; \
} while (0)
#define _PCM_READ_S16_NE(b8) _PCM_READ_S16_BE(b8)
#define _PCM_READ_U16_NE(b8) _PCM_READ_U16_BE(b8)
#define _PCM_READ_S32_NE(b8) _PCM_READ_S32_BE(b8)
#define _PCM_READ_U32_NE(b8) _PCM_READ_U32_BE(b8)
#define _PCM_WRITE_S16_NE(b6) _PCM_WRITE_S16_BE(b8)
#define _PCM_WRITE_U16_NE(b6) _PCM_WRITE_U16_BE(b8)
#define _PCM_WRITE_S32_NE(b6) _PCM_WRITE_S32_BE(b8)
#define _PCM_WRITE_U32_NE(b6) _PCM_WRITE_U32_BE(b8)
#endif
#define _PCM_READ_S24_LE(b8) \
INTPCM_T((b8)[0] | ((b8)[1] << 8) | (((int8_t)((b8)[2])) << 16))
#define _PCM_READ_S24_BE(b8) \
INTPCM_T((b8)[2] | ((b8)[1] << 8) | (((int8_t)((b8)[0])) << 16))
#define _PCM_WRITE_S24_LE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[0] = val; \
b8[1] = val >> 8; \
b8[2] = val >> 16; \
} while (0)
#define _PCM_WRITE_S24_BE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[2] = val; \
b8[1] = val >> 8; \
b8[0] = val >> 16; \
} while (0)
#define _PCM_READ_U24_LE(b8) \
INTPCM_T((b8)[0] | ((b8)[1] << 8) | \
(((int8_t)((b8)[2] ^ 0x80)) << 16))
#define _PCM_READ_U24_BE(b8) \
INTPCM_T((b8)[2] | ((b8)[1] << 8) | \
(((int8_t)((b8)[0] ^ 0x80)) << 16))
#define _PCM_WRITE_U24_LE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[0] = val; \
b8[1] = val >> 8; \
b8[2] = (val >> 16) ^ 0x80; \
} while (0)
#define _PCM_WRITE_U24_BE(bb8, vval) do { \
intpcm_t val = (vval); \
uint8_t *b8 = (bb8); \
b8[2] = val; \
b8[1] = val >> 8; \
b8[0] = (val >> 16) ^ 0x80; \
} while (0)
#if BYTE_ORDER == LITTLE_ENDIAN
#define _PCM_READ_S24_NE(b8) _PCM_READ_S24_LE(b8)
#define _PCM_READ_U24_NE(b8) _PCM_READ_U24_LE(b8)
#define _PCM_WRITE_S24_NE(b6) _PCM_WRITE_S24_LE(b8)
#define _PCM_WRITE_U24_NE(b6) _PCM_WRITE_U24_LE(b8)
#else
#define _PCM_READ_S24_NE(b8) _PCM_READ_S24_BE(b8)
#define _PCM_READ_U24_NE(b8) _PCM_READ_U24_BE(b8)
#define _PCM_WRITE_S24_NE(b6) _PCM_WRITE_S24_BE(b8)
#define _PCM_WRITE_U24_NE(b6) _PCM_WRITE_U24_BE(b8)
#endif
#define _PCM_READ_S8_NE(b8) INTPCM_T(*((int8_t *)(b8)))
#define _PCM_READ_U8_NE(b8) \
INTPCM_T((int8_t)(*((uint8_t *)(b8)) ^ 0x80))
#define _PCM_WRITE_S8_NE(b8, val) do { \
*((int8_t *)(b8)) = (val); \
} while (0)
#define _PCM_WRITE_U8_NE(b8, val) do { \
*((uint8_t *)(b8)) = (val) ^ 0x80; \
} while (0)
#define PCM_READ_S8_NE(b8) _PCM_READ_S8_NE(b8)
#define PCM_READ_U8_NE(b8) _PCM_READ_U8_NE(b8)
#define PCM_WRITE_S8_NE(b8, val) _PCM_WRITE_S8_NE(b8, val)
#define PCM_WRITE_U8_NE(b8, val) _PCM_WRITE_U8_NE(b8, val)
#define PCM_READ_S16_LE(b8) _PCM_READ_S16_LE(b8)
#define PCM_READ_S16_BE(b8) _PCM_READ_S16_BE(b8)
#define PCM_READ_U16_LE(b8) _PCM_READ_U16_LE(b8)
#define PCM_READ_U16_BE(b8) _PCM_READ_U16_BE(b8)
#define PCM_WRITE_S16_LE(b8, val) _PCM_WRITE_S16_LE(b8, val)
#define PCM_WRITE_S16_BE(b8, val) _PCM_WRITE_S16_BE(b8, val)
#define PCM_WRITE_U16_LE(b8, val) _PCM_WRITE_U16_LE(b8, val)
#define PCM_WRITE_U16_BE(b8, val) _PCM_WRITE_U16_BE(b8, val)
#define PCM_READ_S16_NE(b8) _PCM_READ_S16_NE(b8)
#define PCM_READ_U16_NE(b8) _PCM_READ_U16_NE(b8)
#define PCM_WRITE_S16_NE(b8) _PCM_WRITE_S16_NE(b8)
#define PCM_WRITE_U16_NE(b8) _PCM_WRITE_U16_NE(b8)
#define PCM_READ_S24_LE(b8) _PCM_READ_S24_LE(b8)
#define PCM_READ_S24_BE(b8) _PCM_READ_S24_BE(b8)
#define PCM_READ_U24_LE(b8) _PCM_READ_U24_LE(b8)
#define PCM_READ_U24_BE(b8) _PCM_READ_U24_BE(b8)
#define PCM_WRITE_S24_LE(b8, val) _PCM_WRITE_S24_LE(b8, val)
#define PCM_WRITE_S24_BE(b8, val) _PCM_WRITE_S24_BE(b8, val)
#define PCM_WRITE_U24_LE(b8, val) _PCM_WRITE_U24_LE(b8, val)
#define PCM_WRITE_U24_BE(b8, val) _PCM_WRITE_U24_BE(b8, val)
#define PCM_READ_S24_NE(b8) _PCM_READ_S24_NE(b8)
#define PCM_READ_U24_NE(b8) _PCM_READ_U24_NE(b8)
#define PCM_WRITE_S24_NE(b8) _PCM_WRITE_S24_NE(b8)
#define PCM_WRITE_U24_NE(b8) _PCM_WRITE_U24_NE(b8)
#ifdef SND_PCM_64
#define PCM_READ_S32_LE(b8) _PCM_READ_S32_LE(b8)
#define PCM_READ_S32_BE(b8) _PCM_READ_S32_BE(b8)
#define PCM_READ_U32_LE(b8) _PCM_READ_U32_LE(b8)
#define PCM_READ_U32_BE(b8) _PCM_READ_U32_BE(b8)
#define PCM_WRITE_S32_LE(b8, val) _PCM_WRITE_S32_LE(b8, val)
#define PCM_WRITE_S32_BE(b8, val) _PCM_WRITE_S32_BE(b8, val)
#define PCM_WRITE_U32_LE(b8, val) _PCM_WRITE_U32_LE(b8, val)
#define PCM_WRITE_U32_BE(b8, val) _PCM_WRITE_U32_BE(b8, val)
#define PCM_READ_S32_NE(b8) _PCM_READ_S32_NE(b8)
#define PCM_READ_U32_NE(b8) _PCM_READ_U32_NE(b8)
#define PCM_WRITE_S32_NE(b8) _PCM_WRITE_S32_NE(b8)
#define PCM_WRITE_U32_NE(b8) _PCM_WRITE_U32_NE(b8)
#else
#define PCM_READ_S32_LE(b8) (_PCM_READ_S32_LE(b8) >> PCM_FXSHIFT)
#define PCM_READ_S32_BE(b8) (_PCM_READ_S32_BE(b8) >> PCM_FXSHIFT)
#define PCM_READ_U32_LE(b8) (_PCM_READ_U32_LE(b8) >> PCM_FXSHIFT)
#define PCM_READ_U32_BE(b8) (_PCM_READ_U32_BE(b8) >> PCM_FXSHIFT)
#define PCM_READ_S32_NE(b8) (_PCM_READ_S32_NE(b8) >> PCM_FXSHIFT)
#define PCM_READ_U32_NE(b8) (_PCM_READ_U32_NE(b8) >> PCM_FXSHIFT)
#define PCM_WRITE_S32_LE(b8, val) \
_PCM_WRITE_S32_LE(b8, (val) << PCM_FXSHIFT)
#define PCM_WRITE_S32_BE(b8, val) \
_PCM_WRITE_S32_BE(b8, (val) << PCM_FXSHIFT)
#define PCM_WRITE_U32_LE(b8, val) \
_PCM_WRITE_U32_LE(b8, (val) << PCM_FXSHIFT)
#define PCM_WRITE_U32_BE(b8, val) \
_PCM_WRITE_U32_BE(b8, (val) << PCM_FXSHIFT)
#define PCM_WRITE_S32_NE(b8, val) \
_PCM_WRITE_S32_NE(b8, (val) << PCM_FXSHIFT)
#define PCM_WRITE_U32_NE(b8, val) \
_PCM_WRITE_U32_NE(b8, (val) << PCM_FXSHIFT)
#endif
#define PCM_CLAMP_S8(val) \
(((val) > PCM_S8_MAX) ? PCM_S8_MAX : \
(((val) < PCM_S8_MIN) ? PCM_S8_MIN : (val)))
#define PCM_CLAMP_S16(val) \
(((val) > PCM_S16_MAX) ? PCM_S16_MAX : \
(((val) < PCM_S16_MIN) ? PCM_S16_MIN : (val)))
#define PCM_CLAMP_S24(val) \
(((val) > PCM_S24_MAX) ? PCM_S24_MAX : \
(((val) < PCM_S24_MIN) ? PCM_S24_MIN : (val)))
#ifdef SND_PCM_64
#define PCM_CLAMP_S32(val) \
(((val) > PCM_S32_MAX) ? PCM_S32_MAX : \
(((val) < PCM_S32_MIN) ? PCM_S32_MIN : (val)))
#else
#define PCM_CLAMP_S32(val) \
(((val) > PCM_S24_MAX) ? PCM_S32_MAX : \
(((val) < PCM_S24_MIN) ? PCM_S32_MIN : \
((val) << PCM_FXSHIFT)))
#endif
#define PCM_CLAMP_U8(val) PCM_CLAMP_S8(val)
#define PCM_CLAMP_U16(val) PCM_CLAMP_S16(val)
#define PCM_CLAMP_U24(val) PCM_CLAMP_S24(val)
#define PCM_CLAMP_U32(val) PCM_CLAMP_S32(val)
#endif