190da2b28SAriff Abdullah /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 490da2b28SAriff Abdullah * Copyright (c) 2006-2009 Ariff Abdullah <ariff@FreeBSD.org> 590da2b28SAriff Abdullah * All rights reserved. 690da2b28SAriff Abdullah * 790da2b28SAriff Abdullah * Redistribution and use in source and binary forms, with or without 890da2b28SAriff Abdullah * modification, are permitted provided that the following conditions 990da2b28SAriff Abdullah * are met: 1090da2b28SAriff Abdullah * 1. Redistributions of source code must retain the above copyright 1190da2b28SAriff Abdullah * notice, this list of conditions and the following disclaimer. 1290da2b28SAriff Abdullah * 2. Redistributions in binary form must reproduce the above copyright 1390da2b28SAriff Abdullah * notice, this list of conditions and the following disclaimer in the 1490da2b28SAriff Abdullah * documentation and/or other materials provided with the distribution. 1590da2b28SAriff Abdullah * 1690da2b28SAriff Abdullah * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1790da2b28SAriff Abdullah * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1890da2b28SAriff Abdullah * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1990da2b28SAriff Abdullah * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2090da2b28SAriff Abdullah * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2190da2b28SAriff Abdullah * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2290da2b28SAriff Abdullah * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2390da2b28SAriff Abdullah * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2490da2b28SAriff Abdullah * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2590da2b28SAriff Abdullah * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2690da2b28SAriff Abdullah * SUCH DAMAGE. 2790da2b28SAriff Abdullah */ 2890da2b28SAriff Abdullah 2990da2b28SAriff Abdullah #ifndef _SND_PCM_H_ 3090da2b28SAriff Abdullah #define _SND_PCM_H_ 3190da2b28SAriff Abdullah 3290da2b28SAriff Abdullah #include <sys/param.h> 3390da2b28SAriff Abdullah 3490da2b28SAriff Abdullah /* 3590da2b28SAriff Abdullah * Macros for reading/writing PCM sample / int values from bytes array. 3690da2b28SAriff Abdullah * Since every process is done using signed integer (and to make our life 3790da2b28SAriff Abdullah * less miserable), unsigned sample will be converted to its signed 3890da2b28SAriff Abdullah * counterpart and restored during writing back. To avoid overflow, 3990da2b28SAriff Abdullah * we truncate 32bit (and only 32bit) samples down to 24bit (see below 4090da2b28SAriff Abdullah * for the reason), unless SND_PCM_64 is defined. 4190da2b28SAriff Abdullah */ 4290da2b28SAriff Abdullah 4390da2b28SAriff Abdullah /* 4490da2b28SAriff Abdullah * Automatically turn on 64bit arithmetic on suitable archs 45e7d939bdSMarcel Moolenaar * (amd64 64bit, etc..) for wider 32bit samples / integer processing. 4690da2b28SAriff Abdullah */ 4790da2b28SAriff Abdullah #if LONG_BIT >= 64 4890da2b28SAriff Abdullah #undef SND_PCM_64 4990da2b28SAriff Abdullah #define SND_PCM_64 1 5090da2b28SAriff Abdullah #endif 5190da2b28SAriff Abdullah 5290da2b28SAriff Abdullah typedef int32_t intpcm_t; 5390da2b28SAriff Abdullah 5490da2b28SAriff Abdullah typedef int32_t intpcm8_t; 5590da2b28SAriff Abdullah typedef int32_t intpcm16_t; 5690da2b28SAriff Abdullah typedef int32_t intpcm24_t; 5790da2b28SAriff Abdullah 5890da2b28SAriff Abdullah typedef uint32_t uintpcm_t; 5990da2b28SAriff Abdullah 6090da2b28SAriff Abdullah typedef uint32_t uintpcm8_t; 6190da2b28SAriff Abdullah typedef uint32_t uintpcm16_t; 6290da2b28SAriff Abdullah typedef uint32_t uintpcm24_t; 6390da2b28SAriff Abdullah 6490da2b28SAriff Abdullah #ifdef SND_PCM_64 6590da2b28SAriff Abdullah typedef int64_t intpcm32_t; 6690da2b28SAriff Abdullah typedef uint64_t uintpcm32_t; 6790da2b28SAriff Abdullah #else 6890da2b28SAriff Abdullah typedef int32_t intpcm32_t; 6990da2b28SAriff Abdullah typedef uint32_t uintpcm32_t; 7090da2b28SAriff Abdullah #endif 7190da2b28SAriff Abdullah 7290da2b28SAriff Abdullah typedef int64_t intpcm64_t; 7390da2b28SAriff Abdullah typedef uint64_t uintpcm64_t; 7490da2b28SAriff Abdullah 7590da2b28SAriff Abdullah /* 32bit fixed point shift */ 7690da2b28SAriff Abdullah #define PCM_FXSHIFT 8 7790da2b28SAriff Abdullah 7890da2b28SAriff Abdullah #define PCM_S8_MAX 0x7f 7990da2b28SAriff Abdullah #define PCM_S8_MIN -0x80 8090da2b28SAriff Abdullah #define PCM_S16_MAX 0x7fff 8190da2b28SAriff Abdullah #define PCM_S16_MIN -0x8000 8290da2b28SAriff Abdullah #define PCM_S24_MAX 0x7fffff 8390da2b28SAriff Abdullah #define PCM_S24_MIN -0x800000 8490da2b28SAriff Abdullah #ifdef SND_PCM_64 8590da2b28SAriff Abdullah #if LONG_BIT >= 64 8690da2b28SAriff Abdullah #define PCM_S32_MAX 0x7fffffffL 8790da2b28SAriff Abdullah #define PCM_S32_MIN -0x80000000L 8890da2b28SAriff Abdullah #else 8990da2b28SAriff Abdullah #define PCM_S32_MAX 0x7fffffffLL 9090da2b28SAriff Abdullah #define PCM_S32_MIN -0x80000000LL 9190da2b28SAriff Abdullah #endif 9290da2b28SAriff Abdullah #else 9390da2b28SAriff Abdullah #define PCM_S32_MAX 0x7fffffff 9490da2b28SAriff Abdullah #define PCM_S32_MIN (-0x7fffffff - 1) 9590da2b28SAriff Abdullah #endif 9690da2b28SAriff Abdullah 9790da2b28SAriff Abdullah /* Bytes-per-sample definition */ 9890da2b28SAriff Abdullah #define PCM_8_BPS 1 9990da2b28SAriff Abdullah #define PCM_16_BPS 2 10090da2b28SAriff Abdullah #define PCM_24_BPS 3 10190da2b28SAriff Abdullah #define PCM_32_BPS 4 10290da2b28SAriff Abdullah 10390da2b28SAriff Abdullah #define INTPCM_T(v) ((intpcm_t)(v)) 10490da2b28SAriff Abdullah #define INTPCM8_T(v) ((intpcm8_t)(v)) 10590da2b28SAriff Abdullah #define INTPCM16_T(v) ((intpcm16_t)(v)) 10690da2b28SAriff Abdullah #define INTPCM24_T(v) ((intpcm24_t)(v)) 10790da2b28SAriff Abdullah #define INTPCM32_T(v) ((intpcm32_t)(v)) 10890da2b28SAriff Abdullah 10990da2b28SAriff Abdullah #if BYTE_ORDER == LITTLE_ENDIAN 11090da2b28SAriff Abdullah #define _PCM_READ_S16_LE(b8) INTPCM_T(*((int16_t *)(b8))) 11190da2b28SAriff Abdullah #define _PCM_READ_S32_LE(b8) INTPCM_T(*((int32_t *)(b8))) 11290da2b28SAriff Abdullah #define _PCM_READ_S16_BE(b8) \ 11390da2b28SAriff Abdullah INTPCM_T((b8)[1] | (((int8_t)((b8)[0])) << 8)) 11490da2b28SAriff Abdullah #define _PCM_READ_S32_BE(b8) \ 11590da2b28SAriff Abdullah INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) | \ 11690da2b28SAriff Abdullah (((int8_t)((b8)[0])) << 24)) 11790da2b28SAriff Abdullah 11890da2b28SAriff Abdullah #define _PCM_WRITE_S16_LE(b8, val) do { \ 11990da2b28SAriff Abdullah *((int16_t *)(b8)) = (val); \ 12090da2b28SAriff Abdullah } while (0) 12190da2b28SAriff Abdullah #define _PCM_WRITE_S32_LE(b8, val) do { \ 12290da2b28SAriff Abdullah *((int32_t *)(b8)) = (val); \ 12390da2b28SAriff Abdullah } while (0) 12490da2b28SAriff Abdullah #define _PCM_WRITE_S16_BE(bb8, vval) do { \ 12590da2b28SAriff Abdullah intpcm_t val = (vval); \ 12690da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 12790da2b28SAriff Abdullah b8[1] = val; \ 12890da2b28SAriff Abdullah b8[0] = val >> 8; \ 12990da2b28SAriff Abdullah } while (0) 13090da2b28SAriff Abdullah #define _PCM_WRITE_S32_BE(bb8, vval) do { \ 13190da2b28SAriff Abdullah intpcm_t val = (vval); \ 13290da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 13390da2b28SAriff Abdullah b8[3] = val; \ 13490da2b28SAriff Abdullah b8[2] = val >> 8; \ 13590da2b28SAriff Abdullah b8[1] = val >> 16; \ 13690da2b28SAriff Abdullah b8[0] = val >> 24; \ 13790da2b28SAriff Abdullah } while (0) 13890da2b28SAriff Abdullah 13990da2b28SAriff Abdullah #define _PCM_READ_U16_LE(b8) \ 14090da2b28SAriff Abdullah INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000)) 14190da2b28SAriff Abdullah #define _PCM_READ_U32_LE(b8) \ 14290da2b28SAriff Abdullah INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000)) 14390da2b28SAriff Abdullah #define _PCM_READ_U16_BE(b8) \ 14490da2b28SAriff Abdullah INTPCM_T((b8)[1] | (((int8_t)((b8)[0] ^ 0x80)) << 8)) 14590da2b28SAriff Abdullah #define _PCM_READ_U32_BE(b8) \ 14690da2b28SAriff Abdullah INTPCM_T((b8)[3] | ((b8)[2] << 8) | ((b8)[1] << 16) | \ 14790da2b28SAriff Abdullah (((int8_t)((b8)[0] ^ 0x80)) << 24)) 14890da2b28SAriff Abdullah 14990da2b28SAriff Abdullah #define _PCM_WRITE_U16_LE(b8, val) do { \ 15090da2b28SAriff Abdullah *((uint16_t *)(b8)) = (val) ^ 0x8000; \ 15190da2b28SAriff Abdullah } while (0) 15290da2b28SAriff Abdullah #define _PCM_WRITE_U32_LE(b8, val) do { \ 15390da2b28SAriff Abdullah *((uint32_t *)(b8)) = (val) ^ 0x80000000; \ 15490da2b28SAriff Abdullah } while (0) 15590da2b28SAriff Abdullah #define _PCM_WRITE_U16_BE(bb8, vval) do { \ 15690da2b28SAriff Abdullah intpcm_t val = (vval); \ 15790da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 15890da2b28SAriff Abdullah b8[1] = val; \ 15990da2b28SAriff Abdullah b8[0] = (val >> 8) ^ 0x80; \ 16090da2b28SAriff Abdullah } while (0) 16190da2b28SAriff Abdullah #define _PCM_WRITE_U32_BE(bb8, vval) do { \ 16290da2b28SAriff Abdullah intpcm_t val = (vval); \ 16390da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 16490da2b28SAriff Abdullah b8[3] = val; \ 16590da2b28SAriff Abdullah b8[2] = val >> 8; \ 16690da2b28SAriff Abdullah b8[1] = val >> 16; \ 16790da2b28SAriff Abdullah b8[0] = (val >> 24) ^ 0x80; \ 16890da2b28SAriff Abdullah } while (0) 16990da2b28SAriff Abdullah 17090da2b28SAriff Abdullah #define _PCM_READ_S16_NE(b8) _PCM_READ_S16_LE(b8) 17190da2b28SAriff Abdullah #define _PCM_READ_U16_NE(b8) _PCM_READ_U16_LE(b8) 17290da2b28SAriff Abdullah #define _PCM_READ_S32_NE(b8) _PCM_READ_S32_LE(b8) 17390da2b28SAriff Abdullah #define _PCM_READ_U32_NE(b8) _PCM_READ_U32_LE(b8) 17490da2b28SAriff Abdullah #define _PCM_WRITE_S16_NE(b6) _PCM_WRITE_S16_LE(b8) 17590da2b28SAriff Abdullah #define _PCM_WRITE_U16_NE(b6) _PCM_WRITE_U16_LE(b8) 17690da2b28SAriff Abdullah #define _PCM_WRITE_S32_NE(b6) _PCM_WRITE_S32_LE(b8) 17790da2b28SAriff Abdullah #define _PCM_WRITE_U32_NE(b6) _PCM_WRITE_U32_LE(b8) 17890da2b28SAriff Abdullah #else /* !LITTLE_ENDIAN */ 17990da2b28SAriff Abdullah #define _PCM_READ_S16_LE(b8) \ 18090da2b28SAriff Abdullah INTPCM_T((b8)[0] | (((int8_t)((b8)[1])) << 8)) 18190da2b28SAriff Abdullah #define _PCM_READ_S32_LE(b8) \ 18290da2b28SAriff Abdullah INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) | \ 18390da2b28SAriff Abdullah (((int8_t)((b8)[3])) << 24)) 18490da2b28SAriff Abdullah #define _PCM_READ_S16_BE(b8) INTPCM_T(*((int16_t *)(b8))) 18590da2b28SAriff Abdullah #define _PCM_READ_S32_BE(b8) INTPCM_T(*((int32_t *)(b8))) 18690da2b28SAriff Abdullah 18790da2b28SAriff Abdullah #define _PCM_WRITE_S16_LE(bb8, vval) do { \ 18890da2b28SAriff Abdullah intpcm_t val = (vval); \ 18990da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 19090da2b28SAriff Abdullah b8[0] = val; \ 19190da2b28SAriff Abdullah b8[1] = val >> 8; \ 19290da2b28SAriff Abdullah } while (0) 19390da2b28SAriff Abdullah #define _PCM_WRITE_S32_LE(bb8, vval) do { \ 19490da2b28SAriff Abdullah intpcm_t val = (vval); \ 19590da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 19690da2b28SAriff Abdullah b8[0] = val; \ 19790da2b28SAriff Abdullah b8[1] = val >> 8; \ 19890da2b28SAriff Abdullah b8[2] = val >> 16; \ 19990da2b28SAriff Abdullah b8[3] = val >> 24; \ 20090da2b28SAriff Abdullah } while (0) 20190da2b28SAriff Abdullah #define _PCM_WRITE_S16_BE(b8, val) do { \ 20290da2b28SAriff Abdullah *((int16_t *)(b8)) = (val); \ 20390da2b28SAriff Abdullah } while (0) 20490da2b28SAriff Abdullah #define _PCM_WRITE_S32_BE(b8, val) do { \ 20590da2b28SAriff Abdullah *((int32_t *)(b8)) = (val); \ 20690da2b28SAriff Abdullah } while (0) 20790da2b28SAriff Abdullah 20890da2b28SAriff Abdullah #define _PCM_READ_U16_LE(b8) \ 20990da2b28SAriff Abdullah INTPCM_T((b8)[0] | (((int8_t)((b8)[1] ^ 0x80)) << 8)) 21090da2b28SAriff Abdullah #define _PCM_READ_U32_LE(b8) \ 21190da2b28SAriff Abdullah INTPCM_T((b8)[0] | ((b8)[1] << 8) | ((b8)[2] << 16) | \ 21290da2b28SAriff Abdullah (((int8_t)((b8)[3] ^ 0x80)) << 24)) 21390da2b28SAriff Abdullah #define _PCM_READ_U16_BE(b8) \ 21490da2b28SAriff Abdullah INTPCM_T((int16_t)(*((uint16_t *)(b8)) ^ 0x8000)) 21590da2b28SAriff Abdullah #define _PCM_READ_U32_BE(b8) \ 21690da2b28SAriff Abdullah INTPCM_T((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000)) 21790da2b28SAriff Abdullah 21890da2b28SAriff Abdullah #define _PCM_WRITE_U16_LE(bb8, vval) do { \ 21990da2b28SAriff Abdullah intpcm_t val = (vval); \ 22090da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 22190da2b28SAriff Abdullah b8[0] = val; \ 22290da2b28SAriff Abdullah b8[1] = (val >> 8) ^ 0x80; \ 22390da2b28SAriff Abdullah } while (0) 22490da2b28SAriff Abdullah #define _PCM_WRITE_U32_LE(bb8, vval) do { \ 22590da2b28SAriff Abdullah intpcm_t val = (vval); \ 22690da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 22790da2b28SAriff Abdullah b8[0] = val; \ 22890da2b28SAriff Abdullah b8[1] = val >> 8; \ 22990da2b28SAriff Abdullah b8[2] = val >> 16; \ 23090da2b28SAriff Abdullah b8[3] = (val >> 24) ^ 0x80; \ 23190da2b28SAriff Abdullah } while (0) 23290da2b28SAriff Abdullah #define _PCM_WRITE_U16_BE(b8, val) do { \ 23390da2b28SAriff Abdullah *((uint16_t *)(b8)) = (val) ^ 0x8000; \ 23490da2b28SAriff Abdullah } while (0) 23590da2b28SAriff Abdullah #define _PCM_WRITE_U32_BE(b8, val) do { \ 23690da2b28SAriff Abdullah *((uint32_t *)(b8)) = (val) ^ 0x80000000; \ 23790da2b28SAriff Abdullah } while (0) 23890da2b28SAriff Abdullah 23990da2b28SAriff Abdullah #define _PCM_READ_S16_NE(b8) _PCM_READ_S16_BE(b8) 24090da2b28SAriff Abdullah #define _PCM_READ_U16_NE(b8) _PCM_READ_U16_BE(b8) 24190da2b28SAriff Abdullah #define _PCM_READ_S32_NE(b8) _PCM_READ_S32_BE(b8) 24290da2b28SAriff Abdullah #define _PCM_READ_U32_NE(b8) _PCM_READ_U32_BE(b8) 24390da2b28SAriff Abdullah #define _PCM_WRITE_S16_NE(b6) _PCM_WRITE_S16_BE(b8) 24490da2b28SAriff Abdullah #define _PCM_WRITE_U16_NE(b6) _PCM_WRITE_U16_BE(b8) 24590da2b28SAriff Abdullah #define _PCM_WRITE_S32_NE(b6) _PCM_WRITE_S32_BE(b8) 24690da2b28SAriff Abdullah #define _PCM_WRITE_U32_NE(b6) _PCM_WRITE_U32_BE(b8) 24790da2b28SAriff Abdullah #endif /* LITTLE_ENDIAN */ 24890da2b28SAriff Abdullah 24990da2b28SAriff Abdullah #define _PCM_READ_S24_LE(b8) \ 25090da2b28SAriff Abdullah INTPCM_T((b8)[0] | ((b8)[1] << 8) | (((int8_t)((b8)[2])) << 16)) 25190da2b28SAriff Abdullah #define _PCM_READ_S24_BE(b8) \ 25290da2b28SAriff Abdullah INTPCM_T((b8)[2] | ((b8)[1] << 8) | (((int8_t)((b8)[0])) << 16)) 25390da2b28SAriff Abdullah 25490da2b28SAriff Abdullah #define _PCM_WRITE_S24_LE(bb8, vval) do { \ 25590da2b28SAriff Abdullah intpcm_t val = (vval); \ 25690da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 25790da2b28SAriff Abdullah b8[0] = val; \ 25890da2b28SAriff Abdullah b8[1] = val >> 8; \ 25990da2b28SAriff Abdullah b8[2] = val >> 16; \ 26090da2b28SAriff Abdullah } while (0) 26190da2b28SAriff Abdullah #define _PCM_WRITE_S24_BE(bb8, vval) do { \ 26290da2b28SAriff Abdullah intpcm_t val = (vval); \ 26390da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 26490da2b28SAriff Abdullah b8[2] = val; \ 26590da2b28SAriff Abdullah b8[1] = val >> 8; \ 26690da2b28SAriff Abdullah b8[0] = val >> 16; \ 26790da2b28SAriff Abdullah } while (0) 26890da2b28SAriff Abdullah 26990da2b28SAriff Abdullah #define _PCM_READ_U24_LE(b8) \ 27090da2b28SAriff Abdullah INTPCM_T((b8)[0] | ((b8)[1] << 8) | \ 27190da2b28SAriff Abdullah (((int8_t)((b8)[2] ^ 0x80)) << 16)) 27290da2b28SAriff Abdullah #define _PCM_READ_U24_BE(b8) \ 27390da2b28SAriff Abdullah INTPCM_T((b8)[2] | ((b8)[1] << 8) | \ 27490da2b28SAriff Abdullah (((int8_t)((b8)[0] ^ 0x80)) << 16)) 27590da2b28SAriff Abdullah 27690da2b28SAriff Abdullah #define _PCM_WRITE_U24_LE(bb8, vval) do { \ 27790da2b28SAriff Abdullah intpcm_t val = (vval); \ 27890da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 27990da2b28SAriff Abdullah b8[0] = val; \ 28090da2b28SAriff Abdullah b8[1] = val >> 8; \ 28190da2b28SAriff Abdullah b8[2] = (val >> 16) ^ 0x80; \ 28290da2b28SAriff Abdullah } while (0) 28390da2b28SAriff Abdullah #define _PCM_WRITE_U24_BE(bb8, vval) do { \ 28490da2b28SAriff Abdullah intpcm_t val = (vval); \ 28590da2b28SAriff Abdullah uint8_t *b8 = (bb8); \ 28690da2b28SAriff Abdullah b8[2] = val; \ 28790da2b28SAriff Abdullah b8[1] = val >> 8; \ 28890da2b28SAriff Abdullah b8[0] = (val >> 16) ^ 0x80; \ 28990da2b28SAriff Abdullah } while (0) 29090da2b28SAriff Abdullah 29190da2b28SAriff Abdullah #if BYTE_ORDER == LITTLE_ENDIAN 29290da2b28SAriff Abdullah #define _PCM_READ_S24_NE(b8) _PCM_READ_S24_LE(b8) 29390da2b28SAriff Abdullah #define _PCM_READ_U24_NE(b8) _PCM_READ_U24_LE(b8) 29490da2b28SAriff Abdullah #define _PCM_WRITE_S24_NE(b6) _PCM_WRITE_S24_LE(b8) 29590da2b28SAriff Abdullah #define _PCM_WRITE_U24_NE(b6) _PCM_WRITE_U24_LE(b8) 29690da2b28SAriff Abdullah #else /* !LITTLE_ENDIAN */ 29790da2b28SAriff Abdullah #define _PCM_READ_S24_NE(b8) _PCM_READ_S24_BE(b8) 29890da2b28SAriff Abdullah #define _PCM_READ_U24_NE(b8) _PCM_READ_U24_BE(b8) 29990da2b28SAriff Abdullah #define _PCM_WRITE_S24_NE(b6) _PCM_WRITE_S24_BE(b8) 30090da2b28SAriff Abdullah #define _PCM_WRITE_U24_NE(b6) _PCM_WRITE_U24_BE(b8) 30190da2b28SAriff Abdullah #endif /* LITTLE_ENDIAN */ 30290da2b28SAriff Abdullah /* 30390da2b28SAriff Abdullah * 8bit sample is pretty much useless since it doesn't provide 30490da2b28SAriff Abdullah * sufficient dynamic range throughout our filtering process. 30590da2b28SAriff Abdullah * For the sake of completeness, declare it anyway. 30690da2b28SAriff Abdullah */ 30790da2b28SAriff Abdullah #define _PCM_READ_S8_NE(b8) INTPCM_T(*((int8_t *)(b8))) 30890da2b28SAriff Abdullah #define _PCM_READ_U8_NE(b8) \ 30990da2b28SAriff Abdullah INTPCM_T((int8_t)(*((uint8_t *)(b8)) ^ 0x80)) 31090da2b28SAriff Abdullah 31190da2b28SAriff Abdullah #define _PCM_WRITE_S8_NE(b8, val) do { \ 31290da2b28SAriff Abdullah *((int8_t *)(b8)) = (val); \ 31390da2b28SAriff Abdullah } while (0) 31490da2b28SAriff Abdullah #define _PCM_WRITE_U8_NE(b8, val) do { \ 31590da2b28SAriff Abdullah *((uint8_t *)(b8)) = (val) ^ 0x80; \ 31690da2b28SAriff Abdullah } while (0) 31790da2b28SAriff Abdullah 31890da2b28SAriff Abdullah /* 31990da2b28SAriff Abdullah * Common macross. Use this instead of "_", unless we want 32090da2b28SAriff Abdullah * the real sample value. 32190da2b28SAriff Abdullah */ 32290da2b28SAriff Abdullah 32390da2b28SAriff Abdullah /* 8bit */ 32490da2b28SAriff Abdullah #define PCM_READ_S8_NE(b8) _PCM_READ_S8_NE(b8) 32590da2b28SAriff Abdullah #define PCM_READ_U8_NE(b8) _PCM_READ_U8_NE(b8) 32690da2b28SAriff Abdullah #define PCM_WRITE_S8_NE(b8, val) _PCM_WRITE_S8_NE(b8, val) 32790da2b28SAriff Abdullah #define PCM_WRITE_U8_NE(b8, val) _PCM_WRITE_U8_NE(b8, val) 32890da2b28SAriff Abdullah 32990da2b28SAriff Abdullah /* 16bit */ 33090da2b28SAriff Abdullah #define PCM_READ_S16_LE(b8) _PCM_READ_S16_LE(b8) 33190da2b28SAriff Abdullah #define PCM_READ_S16_BE(b8) _PCM_READ_S16_BE(b8) 33290da2b28SAriff Abdullah #define PCM_READ_U16_LE(b8) _PCM_READ_U16_LE(b8) 33390da2b28SAriff Abdullah #define PCM_READ_U16_BE(b8) _PCM_READ_U16_BE(b8) 33490da2b28SAriff Abdullah 33590da2b28SAriff Abdullah #define PCM_WRITE_S16_LE(b8, val) _PCM_WRITE_S16_LE(b8, val) 33690da2b28SAriff Abdullah #define PCM_WRITE_S16_BE(b8, val) _PCM_WRITE_S16_BE(b8, val) 33790da2b28SAriff Abdullah #define PCM_WRITE_U16_LE(b8, val) _PCM_WRITE_U16_LE(b8, val) 33890da2b28SAriff Abdullah #define PCM_WRITE_U16_BE(b8, val) _PCM_WRITE_U16_BE(b8, val) 33990da2b28SAriff Abdullah 34090da2b28SAriff Abdullah #define PCM_READ_S16_NE(b8) _PCM_READ_S16_NE(b8) 34190da2b28SAriff Abdullah #define PCM_READ_U16_NE(b8) _PCM_READ_U16_NE(b8) 34290da2b28SAriff Abdullah #define PCM_WRITE_S16_NE(b8) _PCM_WRITE_S16_NE(b8) 34390da2b28SAriff Abdullah #define PCM_WRITE_U16_NE(b8) _PCM_WRITE_U16_NE(b8) 34490da2b28SAriff Abdullah 34590da2b28SAriff Abdullah /* 24bit */ 34690da2b28SAriff Abdullah #define PCM_READ_S24_LE(b8) _PCM_READ_S24_LE(b8) 34790da2b28SAriff Abdullah #define PCM_READ_S24_BE(b8) _PCM_READ_S24_BE(b8) 34890da2b28SAriff Abdullah #define PCM_READ_U24_LE(b8) _PCM_READ_U24_LE(b8) 34990da2b28SAriff Abdullah #define PCM_READ_U24_BE(b8) _PCM_READ_U24_BE(b8) 35090da2b28SAriff Abdullah 35190da2b28SAriff Abdullah #define PCM_WRITE_S24_LE(b8, val) _PCM_WRITE_S24_LE(b8, val) 35290da2b28SAriff Abdullah #define PCM_WRITE_S24_BE(b8, val) _PCM_WRITE_S24_BE(b8, val) 35390da2b28SAriff Abdullah #define PCM_WRITE_U24_LE(b8, val) _PCM_WRITE_U24_LE(b8, val) 35490da2b28SAriff Abdullah #define PCM_WRITE_U24_BE(b8, val) _PCM_WRITE_U24_BE(b8, val) 35590da2b28SAriff Abdullah 35690da2b28SAriff Abdullah #define PCM_READ_S24_NE(b8) _PCM_READ_S24_NE(b8) 35790da2b28SAriff Abdullah #define PCM_READ_U24_NE(b8) _PCM_READ_U24_NE(b8) 35890da2b28SAriff Abdullah #define PCM_WRITE_S24_NE(b8) _PCM_WRITE_S24_NE(b8) 35990da2b28SAriff Abdullah #define PCM_WRITE_U24_NE(b8) _PCM_WRITE_U24_NE(b8) 36090da2b28SAriff Abdullah 36190da2b28SAriff Abdullah /* 32bit */ 36290da2b28SAriff Abdullah #ifdef SND_PCM_64 36390da2b28SAriff Abdullah #define PCM_READ_S32_LE(b8) _PCM_READ_S32_LE(b8) 36490da2b28SAriff Abdullah #define PCM_READ_S32_BE(b8) _PCM_READ_S32_BE(b8) 36590da2b28SAriff Abdullah #define PCM_READ_U32_LE(b8) _PCM_READ_U32_LE(b8) 36690da2b28SAriff Abdullah #define PCM_READ_U32_BE(b8) _PCM_READ_U32_BE(b8) 36790da2b28SAriff Abdullah 36890da2b28SAriff Abdullah #define PCM_WRITE_S32_LE(b8, val) _PCM_WRITE_S32_LE(b8, val) 36990da2b28SAriff Abdullah #define PCM_WRITE_S32_BE(b8, val) _PCM_WRITE_S32_BE(b8, val) 37090da2b28SAriff Abdullah #define PCM_WRITE_U32_LE(b8, val) _PCM_WRITE_U32_LE(b8, val) 37190da2b28SAriff Abdullah #define PCM_WRITE_U32_BE(b8, val) _PCM_WRITE_U32_BE(b8, val) 37290da2b28SAriff Abdullah 37390da2b28SAriff Abdullah #define PCM_READ_S32_NE(b8) _PCM_READ_S32_NE(b8) 37490da2b28SAriff Abdullah #define PCM_READ_U32_NE(b8) _PCM_READ_U32_NE(b8) 37590da2b28SAriff Abdullah #define PCM_WRITE_S32_NE(b8) _PCM_WRITE_S32_NE(b8) 37690da2b28SAriff Abdullah #define PCM_WRITE_U32_NE(b8) _PCM_WRITE_U32_NE(b8) 37790da2b28SAriff Abdullah #else /* !SND_PCM_64 */ 37890da2b28SAriff Abdullah /* 37990da2b28SAriff Abdullah * 24bit integer ?!? This is quite unfortunate, eh? Get the fact straight: 38090da2b28SAriff Abdullah * Dynamic range for: 38190da2b28SAriff Abdullah * 1) Human =~ 140db 38290da2b28SAriff Abdullah * 2) 16bit = 96db (close enough) 38390da2b28SAriff Abdullah * 3) 24bit = 144db (perfect) 38490da2b28SAriff Abdullah * 4) 32bit = 196db (way too much) 38590da2b28SAriff Abdullah * 5) Bugs Bunny = Gazillion!@%$Erbzzztt-EINVAL db 38690da2b28SAriff Abdullah * Since we're not Bugs Bunny ..uh..err.. avoiding 64bit arithmetic, 24bit 38790da2b28SAriff Abdullah * is pretty much sufficient for our signed integer processing. 38890da2b28SAriff Abdullah */ 38990da2b28SAriff Abdullah #define PCM_READ_S32_LE(b8) (_PCM_READ_S32_LE(b8) >> PCM_FXSHIFT) 39090da2b28SAriff Abdullah #define PCM_READ_S32_BE(b8) (_PCM_READ_S32_BE(b8) >> PCM_FXSHIFT) 39190da2b28SAriff Abdullah #define PCM_READ_U32_LE(b8) (_PCM_READ_U32_LE(b8) >> PCM_FXSHIFT) 39290da2b28SAriff Abdullah #define PCM_READ_U32_BE(b8) (_PCM_READ_U32_BE(b8) >> PCM_FXSHIFT) 39390da2b28SAriff Abdullah 39490da2b28SAriff Abdullah #define PCM_READ_S32_NE(b8) (_PCM_READ_S32_NE(b8) >> PCM_FXSHIFT) 39590da2b28SAriff Abdullah #define PCM_READ_U32_NE(b8) (_PCM_READ_U32_NE(b8) >> PCM_FXSHIFT) 39690da2b28SAriff Abdullah 39790da2b28SAriff Abdullah #define PCM_WRITE_S32_LE(b8, val) \ 39890da2b28SAriff Abdullah _PCM_WRITE_S32_LE(b8, (val) << PCM_FXSHIFT) 39990da2b28SAriff Abdullah #define PCM_WRITE_S32_BE(b8, val) \ 40090da2b28SAriff Abdullah _PCM_WRITE_S32_BE(b8, (val) << PCM_FXSHIFT) 40190da2b28SAriff Abdullah #define PCM_WRITE_U32_LE(b8, val) \ 40290da2b28SAriff Abdullah _PCM_WRITE_U32_LE(b8, (val) << PCM_FXSHIFT) 40390da2b28SAriff Abdullah #define PCM_WRITE_U32_BE(b8, val) \ 40490da2b28SAriff Abdullah _PCM_WRITE_U32_BE(b8, (val) << PCM_FXSHIFT) 40590da2b28SAriff Abdullah 40690da2b28SAriff Abdullah #define PCM_WRITE_S32_NE(b8, val) \ 40790da2b28SAriff Abdullah _PCM_WRITE_S32_NE(b8, (val) << PCM_FXSHIFT) 40890da2b28SAriff Abdullah #define PCM_WRITE_U32_NE(b8, val) \ 40990da2b28SAriff Abdullah _PCM_WRITE_U32_NE(b8, (val) << PCM_FXSHIFT) 41090da2b28SAriff Abdullah #endif /* SND_PCM_64 */ 41190da2b28SAriff Abdullah 41290da2b28SAriff Abdullah #define PCM_CLAMP_S8(val) \ 41390da2b28SAriff Abdullah (((val) > PCM_S8_MAX) ? PCM_S8_MAX : \ 41490da2b28SAriff Abdullah (((val) < PCM_S8_MIN) ? PCM_S8_MIN : (val))) 41590da2b28SAriff Abdullah #define PCM_CLAMP_S16(val) \ 41690da2b28SAriff Abdullah (((val) > PCM_S16_MAX) ? PCM_S16_MAX : \ 41790da2b28SAriff Abdullah (((val) < PCM_S16_MIN) ? PCM_S16_MIN : (val))) 41890da2b28SAriff Abdullah #define PCM_CLAMP_S24(val) \ 41990da2b28SAriff Abdullah (((val) > PCM_S24_MAX) ? PCM_S24_MAX : \ 42090da2b28SAriff Abdullah (((val) < PCM_S24_MIN) ? PCM_S24_MIN : (val))) 42190da2b28SAriff Abdullah 42290da2b28SAriff Abdullah #ifdef SND_PCM_64 42390da2b28SAriff Abdullah #define PCM_CLAMP_S32(val) \ 42490da2b28SAriff Abdullah (((val) > PCM_S32_MAX) ? PCM_S32_MAX : \ 42590da2b28SAriff Abdullah (((val) < PCM_S32_MIN) ? PCM_S32_MIN : (val))) 42690da2b28SAriff Abdullah #else /* !SND_PCM_64 */ 42790da2b28SAriff Abdullah #define PCM_CLAMP_S32(val) \ 42890da2b28SAriff Abdullah (((val) > PCM_S24_MAX) ? PCM_S32_MAX : \ 42990da2b28SAriff Abdullah (((val) < PCM_S24_MIN) ? PCM_S32_MIN : \ 43090da2b28SAriff Abdullah ((val) << PCM_FXSHIFT))) 43190da2b28SAriff Abdullah #endif /* SND_PCM_64 */ 43290da2b28SAriff Abdullah 43390da2b28SAriff Abdullah #define PCM_CLAMP_U8(val) PCM_CLAMP_S8(val) 43490da2b28SAriff Abdullah #define PCM_CLAMP_U16(val) PCM_CLAMP_S16(val) 43590da2b28SAriff Abdullah #define PCM_CLAMP_U24(val) PCM_CLAMP_S24(val) 43690da2b28SAriff Abdullah #define PCM_CLAMP_U32(val) PCM_CLAMP_S32(val) 43790da2b28SAriff Abdullah 43890da2b28SAriff Abdullah #endif /* !_SND_PCM_H_ */ 439