1632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/* 2632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Copyright (C) 2011 The Android Open Source Project 3632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * 4632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * you may not use this file except in compliance with the License. 6632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * You may obtain a copy of the License at 7632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * 8632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * 10632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * See the License for the specific language governing permissions and 14632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * limitations under the License. 15632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 16632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 17632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#ifndef ANDROID_AUDIO_PRIMITIVES_H 18632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#define ANDROID_AUDIO_PRIMITIVES_H 19632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 20632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#include <stdint.h> 21e252f7e4bcb506da9f0f845ee0ca576d13d6a3f4Glenn Kasten#include <stdlib.h> 22632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#include <sys/cdefs.h> 23632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 2431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** \cond */ 25632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten__BEGIN_DECLS 2631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** \endcond */ 27632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 2831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 2931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \file primitives.h 3031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * The memcpy_* conversion routines are designed to work in-place on same dst as src 31e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * buffers only if the types shrink on copy, with the exception of memcpy_to_i16_from_u8(). 32e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * This allows the loops to go upwards for faster cache access (and may be more flexible 33e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for future optimization later). 34e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 35e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 36632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 37632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Dither and clamp pairs of 32-bit input samples (sums) to 16-bit output samples (out). 38d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * Each 32-bit input sample can be viewed as a signed fixed-point Q19.12 of which the 39d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * .12 fraction bits are dithered and the 19 integer bits are clamped to signed 16 bits. 40d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * Alternatively the input can be viewed as Q4.27, of which the lowest .12 of the fraction 41d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * is dithered and the remaining fraction is converted to the output Q.15, with clamping 42d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * on the 4 integer guard bits. 43d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * 44632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * For interleaved stereo, c is the number of sample pairs, 45632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * and out is an array of interleaved pairs of 16-bit samples per channel. 46632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * For mono, c is the number of samples / 2, and out is an array of 16-bit samples. 47632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * The name "dither" is a misnomer; the current implementation does not actually dither 48632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * but uses truncation. This may change. 497ef795a9d1ac0f3f464e0e7a54aeca00bf94215bGlenn Kasten * The out and sums buffers must either be completely separate (non-overlapping), or 507ef795a9d1ac0f3f464e0e7a54aeca00bf94215bGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 51632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 52632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenvoid ditherAndClamp(int32_t* out, const int32_t *sums, size_t c); 53632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 5431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 5531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * Expand and copy samples from unsigned 8-bit offset by 0x80 to signed 16-bit. 5631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 5731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 5831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 5931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 6031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 61ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 62ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 63ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten */ 64ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kastenvoid memcpy_to_i16_from_u8(int16_t *dst, const uint8_t *src, size_t count); 65ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten 6631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 6731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * Shrink and copy samples from signed 16-bit to unsigned 8-bit offset by 0x80. 6831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 6931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 7031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 7131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 7231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 7378da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 7478da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 7578da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 7678da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten */ 7778da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kastenvoid memcpy_to_u8_from_i16(uint8_t *dst, const int16_t *src, size_t count); 7878da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten 7931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 8031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * Copy samples from float to unsigned 8-bit offset by 0x80. 8131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 8231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 8331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 8431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 8531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 8623ef1b379caa5e641367f115d67080ed35069117Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 8723ef1b379caa5e641367f115d67080ed35069117Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 8823ef1b379caa5e641367f115d67080ed35069117Andy Hung * The conversion is done by truncation, without dithering, so it loses resolution. 8923ef1b379caa5e641367f115d67080ed35069117Andy Hung */ 9023ef1b379caa5e641367f115d67080ed35069117Andy Hungvoid memcpy_to_u8_from_float(uint8_t *dst, const float *src, size_t count); 9123ef1b379caa5e641367f115d67080ed35069117Andy Hung 9231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 9331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * Shrink and copy samples from signed 32-bit fixed-point Q0.31 to signed 16-bit Q0.15. 9431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 9531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 9631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 9731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 9831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 995d43605288f444eb30999334642253283941fb3dGlenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 1005d43605288f444eb30999334642253283941fb3dGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 1015d43605288f444eb30999334642253283941fb3dGlenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 1025d43605288f444eb30999334642253283941fb3dGlenn Kasten */ 1035d43605288f444eb30999334642253283941fb3dGlenn Kastenvoid memcpy_to_i16_from_i32(int16_t *dst, const int32_t *src, size_t count); 1045d43605288f444eb30999334642253283941fb3dGlenn Kasten 1053e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1063e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Shrink and copy samples from single-precision floating-point to signed 16-bit. 107db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Each float should be in the range -1.0 to 1.0. Values outside that range are clamped, 10865b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hung * refer to clamp16_from_float(). 10931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 11031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 11131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 11231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 11331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 1145d43605288f444eb30999334642253283941fb3dGlenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 1155d43605288f444eb30999334642253283941fb3dGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 1165d43605288f444eb30999334642253283941fb3dGlenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 1175d43605288f444eb30999334642253283941fb3dGlenn Kasten */ 1185d43605288f444eb30999334642253283941fb3dGlenn Kastenvoid memcpy_to_i16_from_float(int16_t *dst, const float *src, size_t count); 1195d43605288f444eb30999334642253283941fb3dGlenn Kasten 1203e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1213e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point 32-bit Q4.27 to single-precision floating-point. 122aecb15eb579434bbc980892b3707374340e00138Andy Hung * The nominal output float range is [-1.0, 1.0] if the fixed-point range is 123aecb15eb579434bbc980892b3707374340e00138Andy Hung * [0xf8000000, 0x07ffffff]. The full float range is [-16.0, 16.0]. Note the closed range 124d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * at 1.0 and 16.0 is due to rounding on conversion to float. See float_from_q4_27() for details. 12531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 12631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 12731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 12831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 12931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 130aecb15eb579434bbc980892b3707374340e00138Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 131aecb15eb579434bbc980892b3707374340e00138Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 132aecb15eb579434bbc980892b3707374340e00138Andy Hung */ 133b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungvoid memcpy_to_float_from_q4_27(float *dst, const int32_t *src, size_t count); 134aecb15eb579434bbc980892b3707374340e00138Andy Hung 1353e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1363e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point 16 bit Q0.15 to single-precision floating-point. 137e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range [0x8000, 0x7fff]. 138e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * No rounding is needed as the representation is exact. 13931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 14031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 14131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 14231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 14331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 144e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must be completely separate. 145e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 146e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_float_from_i16(float *dst, const int16_t *src, size_t count); 147e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 1483e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1493e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from unsigned fixed-point 8 bit to single-precision floating-point. 15023ef1b379caa5e641367f115d67080ed35069117Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range [0x00, 0xFF]. 15123ef1b379caa5e641367f115d67080ed35069117Andy Hung * No rounding is needed as the representation is exact. 15231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 15331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 15431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 15531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 15631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 15723ef1b379caa5e641367f115d67080ed35069117Andy Hung * The destination and source buffers must be completely separate. 15823ef1b379caa5e641367f115d67080ed35069117Andy Hung */ 15923ef1b379caa5e641367f115d67080ed35069117Andy Hungvoid memcpy_to_float_from_u8(float *dst, const uint8_t *src, size_t count); 16023ef1b379caa5e641367f115d67080ed35069117Andy Hung 1613e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1623e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point packed 24 bit Q0.23 to single-precision floating-point. 163e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The packed 24 bit input is stored in native endian format in a uint8_t byte array. 164e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range [0x800000, 0x7fffff]. 165e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * No rounding is needed as the representation is exact. 16631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 16731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 16831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 16931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 17031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 171e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must be completely separate. 172e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 173e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_float_from_p24(float *dst, const uint8_t *src, size_t count); 174e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 1753e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1763e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point packed 24 bit Q0.23 to signed fixed point 16 bit Q0.15. 177e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The packed 24 bit output is stored in native endian format in a uint8_t byte array. 178e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The data is truncated without rounding. 17931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 18031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 18131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 18231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 18331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 184e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 185e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 186e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 187e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_i16_from_p24(int16_t *dst, const uint8_t *src, size_t count); 188e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 1893e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 1903e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point packed 24 bit Q0.23 to signed fixed-point 32-bit Q0.31. 19195880cb16065385b5633e2f39c7a285d84dfef98Glenn Kasten * The packed 24 bit input is stored in native endian format in a uint8_t byte array. 19295880cb16065385b5633e2f39c7a285d84dfef98Glenn Kasten * The output data range is [0x80000000, 0x7fffff00] at intervals of 0x100. 19331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 19431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 19531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 19631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 19731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 19895880cb16065385b5633e2f39c7a285d84dfef98Glenn Kasten * The destination and source buffers must be completely separate. 19995880cb16065385b5633e2f39c7a285d84dfef98Glenn Kasten */ 20095880cb16065385b5633e2f39c7a285d84dfef98Glenn Kastenvoid memcpy_to_i32_from_p24(int32_t *dst, const uint8_t *src, size_t count); 20195880cb16065385b5633e2f39c7a285d84dfef98Glenn Kasten 2023e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2033e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed point 16 bit Q0.15 to signed fixed-point packed 24 bit Q0.23. 204a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 205e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output data range is [0x800000, 0x7fff00] (not full). 206e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Nevertheless there is no DC offset on the output, if the input has no DC offset. 20731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 20831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 20931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 21031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 21131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 212e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must be completely separate. 213e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 214e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_p24_from_i16(uint8_t *dst, const int16_t *src, size_t count); 215e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 2163e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2173e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from single-precision floating-point to signed fixed-point packed 24 bit Q0.23. 218a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 219e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The data is clamped and rounded to nearest, ties away from zero. See clamp24_from_float() 220e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for details. 22131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 22231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 22331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 22431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 22531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 226e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 227e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 228e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 229e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_p24_from_float(uint8_t *dst, const float *src, size_t count); 230e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 2313e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2323e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point 32-bit Q8.23 to signed fixed-point packed 24 bit Q0.23. 233a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 234eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * The data is clamped to the range is [0x800000, 0x7fffff]. 23531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 23631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 23731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 23831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 23931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 240eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * The destination and source buffers must be completely separate. 241eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten */ 242eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kastenvoid memcpy_to_p24_from_q8_23(uint8_t *dst, const int32_t *src, size_t count); 243eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten 2443e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2453e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Shrink and copy samples from signed 32-bit fixed-point Q0.31 246daa1a00524b5628676075cf17e1699e904252303Glenn Kasten * to signed fixed-point packed 24 bit Q0.23. 247daa1a00524b5628676075cf17e1699e904252303Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 24831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 24931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 25031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 25131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 25231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 253daa1a00524b5628676075cf17e1699e904252303Glenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 254daa1a00524b5628676075cf17e1699e904252303Glenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 255daa1a00524b5628676075cf17e1699e904252303Glenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 256daa1a00524b5628676075cf17e1699e904252303Glenn Kasten */ 257daa1a00524b5628676075cf17e1699e904252303Glenn Kastenvoid memcpy_to_p24_from_i32(uint8_t *dst, const int32_t *src, size_t count); 258daa1a00524b5628676075cf17e1699e904252303Glenn Kasten 2593e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2603e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed point 16-bit Q0.15 to signed fixed-point 32-bit Q8.23. 261d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The output data range is [0xff800000, 0x007fff00] at intervals of 0x100. 26231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 26331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 26431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 26531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 26631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 267d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must be completely separate. 268d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 269d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_q8_23_from_i16(int32_t *dst, const int16_t *src, size_t count); 270d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 2713e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2723e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from single-precision floating-point to signed fixed-point 32-bit Q8.23. 273d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * This copy will clamp the Q8.23 representation to [0xff800000, 0x007fffff] even though there 274d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * are guard bits available. Fractional lsb is rounded to nearest, ties away from zero. 275d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * See clamp24_from_float() for details. 27631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 27731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 27831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 27931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 28031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 281d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 282d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 283d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 284d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_q8_23_from_float_with_clamp(int32_t *dst, const float *src, size_t count); 285d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 2863e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2873e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed point packed 24-bit Q0.23 to signed fixed-point 32-bit Q8.23. 28878ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George * The output data range is [0xff800000, 0x007fffff]. 28931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 29031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 29131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 29231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 29331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 29478ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George * The destination and source buffers must be completely separate. 29578ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George */ 29678ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew Georgevoid memcpy_to_q8_23_from_p24(int32_t *dst, const uint8_t *src, size_t count); 29778ac9f8cb0d6ae6a01ad9d2329ecf18db3a1f050Haynes Mathew George 2983e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 2993e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from single-precision floating-point to signed fixed-point 32-bit Q4.27. 300b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * The conversion will use the full available Q4.27 range, including guard bits. 301b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Fractional lsb is rounded to nearest, ties away from zero. 302b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * See clampq4_27_from_float() for details. 30331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 30431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 30531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 30631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 30731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 308b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 309b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 310b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 311b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungvoid memcpy_to_q4_27_from_float(int32_t *dst, const float *src, size_t count); 312b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 3133e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 3143e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point 32-bit Q8.23 to signed fixed point 16-bit Q0.15. 315d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The data is clamped, and truncated without rounding. 31631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 31731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 31831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 31931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 32031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 321d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 322d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 323d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 324d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_i16_from_q8_23(int16_t *dst, const int32_t *src, size_t count); 325d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 3263e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 3273e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point 32-bit Q8.23 to single-precision floating-point. 328d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The nominal output float range is [-1.0, 1.0) for the fixed-point 329d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * range [0xff800000, 0x007fffff]. The maximum output float range is [-256.0, 256.0). 330d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * No rounding is needed as the representation is exact for nominal values. 331d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * Rounding for overflow values is to nearest, ties to even. 33231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 33331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 33431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 33531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 33631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 337d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 338d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 339d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 340d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_float_from_q8_23(float *dst, const int32_t *src, size_t count); 341d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 3423e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 3433e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed point 16-bit Q0.15 to signed fixed-point 32-bit Q0.31. 3442c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The output data range is [0x80000000, 0x7fff0000] at intervals of 0x10000. 34531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 34631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 34731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 34831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 34931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 3502c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The destination and source buffers must be completely separate. 3512c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 3522c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungvoid memcpy_to_i32_from_i16(int32_t *dst, const int16_t *src, size_t count); 3532c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 3543e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 3553e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from single-precision floating-point to signed fixed-point 32-bit Q0.31. 3562c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * If rounding is needed on truncation, the fractional lsb is rounded to nearest, 3572c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * ties away from zero. See clamp32_from_float() for details. 35831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 35931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 36031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 36131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 36231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 3632c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 3642c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 3652c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 3662c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungvoid memcpy_to_i32_from_float(int32_t *dst, const float *src, size_t count); 3672c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 3683e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 3693e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy samples from signed fixed-point 32-bit Q0.31 to single-precision floating-point. 3702c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The float range is [-1.0, 1.0] for the fixed-point range [0x80000000, 0x7fffffff]. 3712c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding is done according to float_from_i32(). 37231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 37331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 37431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 37531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of samples to copy 37631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 3772c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 3782c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 3792c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 3802c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungvoid memcpy_to_float_from_i32(float *dst, const int32_t *src, size_t count); 3812c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 38231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 38331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * Downmix pairs of interleaved stereo input 16-bit samples to mono output 16-bit samples. 38431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 38531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 38631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 38731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of stereo frames to downmix 38831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 3897a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * The destination and source buffers must be completely separate (non-overlapping). 390217c0a4ac853f8fb6e64bc0c59e289b4fc2006b2Glenn Kasten * The current implementation truncates the mean rather than dither, but this may change. 3917a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten */ 3927a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kastenvoid downmix_to_mono_i16_from_stereo_i16(int16_t *dst, const int16_t *src, size_t count); 3937a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten 3943e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 3953e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Upmix mono input 16-bit samples to pairs of interleaved stereo output 16-bit samples by 3967a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * duplicating. 39731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 39831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 39931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 40031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of mono samples to upmix 40131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 4027a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * The destination and source buffers must be completely separate (non-overlapping). 4037a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten */ 4047a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kastenvoid upmix_to_stereo_i16_from_mono_i16(int16_t *dst, const int16_t *src, size_t count); 4057a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten 4063e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 4073e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Downmix pairs of interleaved stereo input float samples to mono output float samples 4089c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung * by averaging the stereo pair together. 40931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 41031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 41131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 41231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of stereo frames to downmix 41331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 4149c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung * The destination and source buffers must be completely separate (non-overlapping), 4159c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung * or they must both start at the same address. 4169c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung */ 4179c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hungvoid downmix_to_mono_float_from_stereo_float(float *dst, const float *src, size_t count); 4189c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung 4193e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 4203e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Upmix mono input float samples to pairs of interleaved stereo output float samples by 4219c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung * duplicating. 42231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 42331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 42431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 42531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of mono samples to upmix 42631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 4279c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung * The destination and source buffers must be completely separate (non-overlapping). 4289c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung */ 4299c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hungvoid upmix_to_stereo_float_from_mono_float(float *dst, const float *src, size_t count); 4309c8dd45c203ac7f9fa558b9436fa133a3026d62aAndy Hung 43131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 43231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the total number of non-zero 32-bit samples. 43331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten */ 434eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroMono32(const int32_t *samples, size_t count); 435eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 43631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 43731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the total number of non-zero 16-bit samples. 43831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten */ 439eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroMono16(const int16_t *samples, size_t count); 440eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 44131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 44231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the total number of non-zero stereo frames, where a frame is considered non-zero 44331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * if either of its constituent 32-bit samples is non-zero. 444eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten */ 445eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroStereo32(const int32_t *frames, size_t count); 446eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 44731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** 44831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the total number of non-zero stereo frames, where a frame is considered non-zero 44931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * if either of its constituent 16-bit samples is non-zero. 450eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten */ 451eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroStereo16(const int16_t *frames, size_t count); 452eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 4533e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 4543e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy frames, selecting source samples based on a source channel mask to fit 4553af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * the destination channel mask. Unmatched channels in the destination channel mask 4563af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * are zero filled. Unmatched channels in the source channel mask are dropped. 4573af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Channels present in the channel mask are represented by set bits in the 4583af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * uint32_t value and are matched without further interpretation. 45931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 46031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 46131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst_mask Bit mask corresponding to destination channels present 46231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 46331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src_mask Bit mask corresponding to source channels present 46431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param sample_size Size of each sample in bytes. Must be 1, 2, 3, or 4. 46531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of frames to copy 46631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 4673af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The destination and source buffers must be completely separate (non-overlapping). 4683af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * If the sample size is not in range, the function will abort. 4693af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung */ 4703af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungvoid memcpy_by_channel_mask(void *dst, uint32_t dst_mask, 4713af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const void *src, uint32_t src_mask, size_t sample_size, size_t count); 4723af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 4733e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 4743e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Copy frames, selecting source samples based on an index array (idxary). 4753af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The idxary[] consists of dst_channels number of elements. 4763af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The ith element if idxary[] corresponds the ith destination channel. 4773af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * A non-negative value is the channel index in the source frame. 4783af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * A negative index (-1) represents filling with 0. 4793af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 4803af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Example: Swapping L and R channels for stereo streams 48131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * <PRE> 4823af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[0] = 1; 4833af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[1] = 0; 48431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * </PRE> 4853af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 4863af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Example: Copying a mono source to the front center 5.1 channel 48731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * <PRE> 4883af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[0] = -1; 4893af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[1] = -1; 4903af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[2] = 0; 4913af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[3] = -1; 4923af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[4] = -1; 4933af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[5] = -1; 49431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * </PRE> 4953af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 4963af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * This copy allows swizzling of channels or replication of channels. 4973af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 49831e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst Destination buffer 49931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst_channels Number of destination channels per frame 50031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src Source buffer 50131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src_channels Number of source channels per frame 50231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxary Array of indices representing channels in the source frame 50331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param sample_size Size of each sample in bytes. Must be 1, 2, 3, or 4. 50431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param count Number of frames to copy 50531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 5063af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The destination and source buffers must be completely separate (non-overlapping). 5073af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * If the sample size is not in range, the function will abort. 5083af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung */ 5093af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungvoid memcpy_by_index_array(void *dst, uint32_t dst_channels, 5103af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const void *src, uint32_t src_channels, 5113af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const int8_t *idxary, size_t sample_size, size_t count); 5123af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 5133e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 5143e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Prepares an index array (idxary) from channel masks, which can be later 51531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * used by memcpy_by_index_array(). 51631e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 51731e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the number of array elements required. 5183af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * This may be greater than idxcount, so the return value should be checked 51931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * if idxary size is less than 32. 52031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 52131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * Note that idxary is a caller allocated array 5223af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * of at least as many channels as present in the dst_mask. 5233af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Channels present in the channel mask are represented by set bits in the 5243af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * uint32_t value and are matched without further interpretation. 5253af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 5265a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * This function is typically used for converting audio data with different 5275a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * channel position masks. 5285a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * 52931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxary Updated array of indices of channels in the src frame for the dst frame 53031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxcount Number of caller allocated elements in idxary 53131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst_mask Bit mask corresponding to destination channels present 53231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src_mask Bit mask corresponding to source channels present 5333af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung */ 5343af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungsize_t memcpy_by_index_array_initialization(int8_t *idxary, size_t idxcount, 5353af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t dst_mask, uint32_t src_mask); 5363af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 5373e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 5383e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Prepares an index array (idxary) from channel masks, which can be later 53931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * used by memcpy_by_index_array(). 54031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 54131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the number of array elements required. 5425a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * 5435a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * For a source channel index mask, the source channels will map to the destination 5445a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * channels as if counting the set bits in dst_mask in order from lsb to msb 5455a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * (zero bits are ignored). The ith bit of the src_mask corresponds to the 5465a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * ith SET bit of dst_mask and the ith destination channel. Hence, a zero ith 5475a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * bit of the src_mask indicates that the ith destination channel plays silence. 5485a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung * 54931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxary Updated array of indices of channels in the src frame for the dst frame 55031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxcount Number of caller allocated elements in idxary 55131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst_mask Bit mask corresponding to destination channels present 55231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src_mask Bit mask corresponding to source channels present 5535a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung */ 5545a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hungsize_t memcpy_by_index_array_initialization_src_index(int8_t *idxary, size_t idxcount, 5555a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung uint32_t dst_mask, uint32_t src_mask); 5565a0d0285cdd75cd5c94e020311830d634d6587b0Andy Hung 5573e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 5583e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Prepares an index array (idxary) from channel mask bits, which can be later 55931e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * used by memcpy_by_index_array(). 56031e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * 56131e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \return the number of array elements required. 562291a1948093850aa87f60264680404b2b96ee327Andy Hung * 563291a1948093850aa87f60264680404b2b96ee327Andy Hung * This initialization is for a destination channel index mask from a positional 564291a1948093850aa87f60264680404b2b96ee327Andy Hung * source mask. 565291a1948093850aa87f60264680404b2b96ee327Andy Hung * 566291a1948093850aa87f60264680404b2b96ee327Andy Hung * For an destination channel index mask, the input channels will map 567291a1948093850aa87f60264680404b2b96ee327Andy Hung * to the destination channels, with the ith SET bit in the source bits corresponding 568291a1948093850aa87f60264680404b2b96ee327Andy Hung * to the ith bit in the destination bits. If there is a zero bit in the middle 569291a1948093850aa87f60264680404b2b96ee327Andy Hung * of set destination bits (unlikely), the corresponding source channel will 570291a1948093850aa87f60264680404b2b96ee327Andy Hung * be dropped. 571291a1948093850aa87f60264680404b2b96ee327Andy Hung * 57231e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxary Updated array of indices of channels in the src frame for the dst frame 57331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param idxcount Number of caller allocated elements in idxary 57431e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param dst_mask Bit mask corresponding to destination channels present 57531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten * \param src_mask Bit mask corresponding to source channels present 576291a1948093850aa87f60264680404b2b96ee327Andy Hung */ 577291a1948093850aa87f60264680404b2b96ee327Andy Hungsize_t memcpy_by_index_array_initialization_dst_index(int8_t *idxary, size_t idxcount, 578291a1948093850aa87f60264680404b2b96ee327Andy Hung uint32_t dst_mask, uint32_t src_mask); 579291a1948093850aa87f60264680404b2b96ee327Andy Hung 580632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 581632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Clamp (aka hard limit or clip) a signed 32-bit sample to 16-bit range. 582632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 583632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline int16_t clamp16(int32_t sample) 584632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 585632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if ((sample>>15) ^ (sample>>31)) 586632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten sample = 0x7FFF ^ (sample>>31); 587632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return sample; 588632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 589632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 5903e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 591db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Convert a IEEE 754 single precision float [-1.0, 1.0) to int16_t [-32768, 32767] 592db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * with clamping. Note the open bound at 1.0, values within 1/65536 of 1.0 map 593db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * to 32767 instead of 32768 (early clamping due to the smaller positive integer subrange). 594db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * 595db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -32768 and 32767, 596db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * including -Inf and +Inf. NaN will generally be treated either as -32768 or 32767, 597db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * depending on the sign bit inside NaN (whose representation is not unique). 598db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Nevertheless, strictly speaking, NaN behavior should be considered undefined. 599db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * 600db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Rounding of 0.5 lsb is to even (default for IEEE 754). 601db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 60265b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hungstatic inline int16_t clamp16_from_float(float f) 603db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung{ 604db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* Offset is used to expand the valid range of [-1.0, 1.0) into the 16 lsbs of the 605db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * floating point significand. The normal shift is 3<<22, but the -15 offset 606db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * is used to multiply by 32768. 607db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 608db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const float offset = (float)(3 << (22 - 15)); 609db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* zero = (0x10f << 22) = 0x43c00000 (not directly used) */ 610db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const int32_t limneg = (0x10f << 22) /*zero*/ - 32768; /* 0x43bf8000 */ 611db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const int32_t limpos = (0x10f << 22) /*zero*/ + 32767; /* 0x43c07fff */ 612db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 613db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung union { 614db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung float f; 615db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung int32_t i; 616db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung } u; 617db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 618db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.f = f + offset; /* recenter valid range */ 619db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* Now the valid range is represented as integers between [limneg, limpos]. 620db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Clamp using the fact that float representation (as an integer) is an ordered set. 621db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 622db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung if (u.i < limneg) 623db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.i = -32768; 624db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung else if (u.i > limpos) 625db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.i = 32767; 626db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung return u.i; /* Return lower 16 bits, the part of interest in the significand. */ 627db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung} 628db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 6293e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 63023ef1b379caa5e641367f115d67080ed35069117Andy Hung * Convert a IEEE 754 single precision float [-1.0, 1.0) to uint8_t [0, 0xff] 63123ef1b379caa5e641367f115d67080ed35069117Andy Hung * with clamping. Note the open bound at 1.0, values within 1/128 of 1.0 map 63223ef1b379caa5e641367f115d67080ed35069117Andy Hung * to 255 instead of 256 (early clamping due to the smaller positive integer subrange). 63323ef1b379caa5e641367f115d67080ed35069117Andy Hung * 63423ef1b379caa5e641367f115d67080ed35069117Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to 0 and 255, 63523ef1b379caa5e641367f115d67080ed35069117Andy Hung * including -Inf and +Inf. NaN will generally be treated either as 0 or 255, 63623ef1b379caa5e641367f115d67080ed35069117Andy Hung * depending on the sign bit inside NaN (whose representation is not unique). 63723ef1b379caa5e641367f115d67080ed35069117Andy Hung * Nevertheless, strictly speaking, NaN behavior should be considered undefined. 63823ef1b379caa5e641367f115d67080ed35069117Andy Hung * 63923ef1b379caa5e641367f115d67080ed35069117Andy Hung * Rounding of 0.5 lsb is to even (default for IEEE 754). 64023ef1b379caa5e641367f115d67080ed35069117Andy Hung */ 64123ef1b379caa5e641367f115d67080ed35069117Andy Hungstatic inline uint8_t clamp8_from_float(float f) 64223ef1b379caa5e641367f115d67080ed35069117Andy Hung{ 64323ef1b379caa5e641367f115d67080ed35069117Andy Hung /* Offset is used to expand the valid range of [-1.0, 1.0) into the 16 lsbs of the 64423ef1b379caa5e641367f115d67080ed35069117Andy Hung * floating point significand. The normal shift is 3<<22, but the -7 offset 64523ef1b379caa5e641367f115d67080ed35069117Andy Hung * is used to multiply by 128. 64623ef1b379caa5e641367f115d67080ed35069117Andy Hung */ 64723ef1b379caa5e641367f115d67080ed35069117Andy Hung static const float offset = (float)((3 << (22 - 7)) + 1 /* to cancel -1.0 */); 64823ef1b379caa5e641367f115d67080ed35069117Andy Hung /* zero = (0x11f << 22) = 0x47c00000 */ 64923ef1b379caa5e641367f115d67080ed35069117Andy Hung static const int32_t limneg = (0x11f << 22) /*zero*/; 65023ef1b379caa5e641367f115d67080ed35069117Andy Hung static const int32_t limpos = (0x11f << 22) /*zero*/ + 255; /* 0x47c000ff */ 65123ef1b379caa5e641367f115d67080ed35069117Andy Hung 65223ef1b379caa5e641367f115d67080ed35069117Andy Hung union { 65323ef1b379caa5e641367f115d67080ed35069117Andy Hung float f; 65423ef1b379caa5e641367f115d67080ed35069117Andy Hung int32_t i; 65523ef1b379caa5e641367f115d67080ed35069117Andy Hung } u; 65623ef1b379caa5e641367f115d67080ed35069117Andy Hung 65723ef1b379caa5e641367f115d67080ed35069117Andy Hung u.f = f + offset; /* recenter valid range */ 65823ef1b379caa5e641367f115d67080ed35069117Andy Hung /* Now the valid range is represented as integers between [limneg, limpos]. 65923ef1b379caa5e641367f115d67080ed35069117Andy Hung * Clamp using the fact that float representation (as an integer) is an ordered set. 66023ef1b379caa5e641367f115d67080ed35069117Andy Hung */ 66123ef1b379caa5e641367f115d67080ed35069117Andy Hung if (u.i < limneg) 66223ef1b379caa5e641367f115d67080ed35069117Andy Hung return 0; 66323ef1b379caa5e641367f115d67080ed35069117Andy Hung if (u.i > limpos) 66423ef1b379caa5e641367f115d67080ed35069117Andy Hung return 255; 66523ef1b379caa5e641367f115d67080ed35069117Andy Hung return u.i; /* Return lower 8 bits, the part of interest in the significand. */ 66623ef1b379caa5e641367f115d67080ed35069117Andy Hung} 66723ef1b379caa5e641367f115d67080ed35069117Andy Hung 6683e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 6693e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a single-precision floating point value to a Q0.23 integer value, stored in a 670e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 32 bit signed integer (technically stored as Q8.23, but clamped to Q0.23). 671e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 672e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Rounds to nearest, ties away from 0. 673e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 674e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -8388608 and 8388607, 675e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 676e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * depending on hardware and future implementation of this function. 677e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 678e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline int32_t clamp24_from_float(float f) 679e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 680e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float scale = (float)(1 << 23); 681e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float limpos = 0x7fffff / scale; 682e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float limneg = -0x800000 / scale; 683e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 684e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung if (f <= limneg) { 685e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return -0x800000; 686e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung } else if (f >= limpos) { 687e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return 0x7fffff; 688e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung } 689e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung f *= scale; 690e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* integer conversion is through truncation (though int to float is not). 691e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * ensure that we round to nearest, ties away from 0. 692e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 693e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 694e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 695e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 6963e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 6973e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a signed fixed-point 32-bit Q8.23 value to a Q0.23 integer value, 698eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * stored in a 32-bit signed integer (technically stored as Q8.23, but clamped to Q0.23). 699eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * 700eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * Values outside the range [-0x800000, 0x7fffff] are clamped to that range. 701eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten */ 702eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kastenstatic inline int32_t clamp24_from_q8_23(int32_t ival) 703eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten{ 704eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten static const int32_t limpos = 0x7fffff; 705eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten static const int32_t limneg = -0x800000; 706eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten if (ival < limneg) { 707eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return limneg; 708eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } else if (ival > limpos) { 709eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return limpos; 710eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } else { 711eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return ival; 712eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } 713eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten} 714eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten 7153e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 7163e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a single-precision floating point value to a Q4.27 integer value. 717b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Rounds to nearest, ties away from 0. 718b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * 719b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Values outside the range [-16.0, 16.0) are properly clamped to -2147483648 and 2147483647, 720b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 721b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * depending on hardware and future implementation of this function. 722b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 723b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungstatic inline int32_t clampq4_27_from_float(float f) 724b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung{ 725b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float scale = (float)(1UL << 27); 726b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float limpos = 16.; 727b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float limneg = -16.; 728b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 729b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung if (f <= limneg) { 730b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return -0x80000000; /* or 0x80000000 */ 731b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } else if (f >= limpos) { 732b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return 0x7fffffff; 733b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } 734b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung f *= scale; 735b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung /* integer conversion is through truncation (though int to float is not). 736b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * ensure that we round to nearest, ties away from 0. 737b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 738b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 739b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung} 740b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 7413e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 7423e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a single-precision floating point value to a Q0.31 integer value. 7432c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounds to nearest, ties away from 0. 7442c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * 7452c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -2147483648 and 2147483647, 7462c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 7472c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * depending on hardware and future implementation of this function. 7482c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 7492c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungstatic inline int32_t clamp32_from_float(float f) 7502c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung{ 7512c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float scale = (float)(1UL << 31); 7522c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float limpos = 1.; 7532c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float limneg = -1.; 7542c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 7552c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung if (f <= limneg) { 756b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return -0x80000000; /* or 0x80000000 */ 7572c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung } else if (f >= limpos) { 7582c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return 0x7fffffff; 7592c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung } 7602c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung f *= scale; 7612c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung /* integer conversion is through truncation (though int to float is not). 7622c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * ensure that we round to nearest, ties away from 0. 7632c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 7642c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 7652c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung} 7662c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 7673e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 7683e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a signed fixed-point 32-bit Q4.27 value to single-precision floating-point. 76942605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * The nominal output float range is [-1.0, 1.0] if the fixed-point range is 77042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * [0xf8000000, 0x07ffffff]. The full float range is [-16.0, 16.0]. 77142605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * 77242605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * Note the closed range at 1.0 and 16.0 is due to rounding on conversion to float. 77342605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * In more detail: if the fixed-point integer exceeds 24 bit significand of single 77442605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * precision floating point, the 0.5 lsb in the significand conversion will round 77542605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * towards even, as per IEEE 754 default. 77642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung */ 777d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hungstatic inline float float_from_q4_27(int32_t ival) 77842605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung{ 779d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung /* The scale factor is the reciprocal of the fractional bits. 78042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * 78142605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * Since the scale factor is a power of 2, the scaling is exact, and there 78242605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * is no rounding due to the multiplication - the bit pattern is preserved. 78342605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * However, there may be rounding due to the fixed-point to float conversion, 78442605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * as described above. 78542605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung */ 786d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung static const float scale = 1. / (float)(1UL << 27); 78742605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung 78842605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung return ival * scale; 78942605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung} 79042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung 7913e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 7923e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert an unsigned fixed-point 32-bit U4.28 value to single-precision floating-point. 793de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * The nominal output float range is [0.0, 1.0] if the fixed-point range is 794de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * [0x00000000, 0x10000000]. The full float range is [0.0, 16.0]. 795de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * 796de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Note the closed range at 1.0 and 16.0 is due to rounding on conversion to float. 797de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * In more detail: if the fixed-point integer exceeds 24 bit significand of single 798de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * precision floating point, the 0.5 lsb in the significand conversion will round 799de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * towards even, as per IEEE 754 default. 800de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 801de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline float float_from_u4_28(uint32_t uval) 802de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 803de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = 1. / (float)(1UL << 28); 804de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 805de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return uval * scale; 806de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 807de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 8083e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 8093e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert an unsigned fixed-point 16-bit U4.12 value to single-precision floating-point. 810de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * The nominal output float range is [0.0, 1.0] if the fixed-point range is 811de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * [0x0000, 0x1000]. The full float range is [0.0, 16.0). 812de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 813de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline float float_from_u4_12(uint16_t uval) 814de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 815de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = 1. / (float)(1UL << 12); 816de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 817de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return uval * scale; 818de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 819de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 8203e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 8213e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a single-precision floating point value to a U4.28 integer value. 822de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Rounds to nearest, ties away from 0. 823de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * 824de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Values outside the range [0, 16.0] are properly clamped to [0, 4294967295] 825de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 826de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * depending on hardware and future implementation of this function. 827de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 828de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline uint32_t u4_28_from_float(float f) 829de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 830de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = (float)(1 << 28); 831de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float limpos = 0xffffffffUL / scale; 832de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 833de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung if (f <= 0.) { 834de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0; 835de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } else if (f >= limpos) { 836de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0xffffffff; 837de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } 838de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung /* integer conversion is through truncation (though int to float is not). 839de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * ensure that we round to nearest, ties away from 0. 840de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 841de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return f * scale + 0.5; 842de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 843de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 8443e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 8453e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a single-precision floating point value to a U4.12 integer value. 846de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Rounds to nearest, ties away from 0. 847de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * 848de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Values outside the range [0, 16.0) are properly clamped to [0, 65535] 849de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 850de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * depending on hardware and future implementation of this function. 851de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 852de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline uint16_t u4_12_from_float(float f) 853de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 854de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = (float)(1 << 12); 855de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float limpos = 0xffff / scale; 856de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 857de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung if (f <= 0.) { 858de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0; 859de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } else if (f >= limpos) { 860de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0xffff; 861de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } 862de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung /* integer conversion is through truncation (though int to float is not). 863de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * ensure that we round to nearest, ties away from 0. 864de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 865de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return f * scale + 0.5; 866de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 867de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 8683e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 8693e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a signed fixed-point 16-bit Q0.15 value to single-precision floating-point. 870e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range 871e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * [0x8000, 0x7fff]. 872e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 873e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * There is no rounding, the conversion and representation is exact. 874e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 875e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline float float_from_i16(int16_t ival) 876e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 877e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* The scale factor is the reciprocal of the nominal 16 bit integer 878e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * half-sided range (32768). 879e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 880e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Since the scale factor is a power of 2, the scaling is exact, and there 881e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * is no rounding due to the multiplication - the bit pattern is preserved. 882e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 883e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float scale = 1. / (float)(1UL << 15); 884e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 885e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return ival * scale; 886e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 887e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 8883e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 8893e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert an unsigned fixed-point 8-bit U0.8 value to single-precision floating-point. 89023ef1b379caa5e641367f115d67080ed35069117Andy Hung * The nominal output float range is [-1.0, 1.0) if the fixed-point range is 89123ef1b379caa5e641367f115d67080ed35069117Andy Hung * [0x00, 0xff]. 89223ef1b379caa5e641367f115d67080ed35069117Andy Hung */ 89323ef1b379caa5e641367f115d67080ed35069117Andy Hungstatic inline float float_from_u8(uint8_t uval) 89423ef1b379caa5e641367f115d67080ed35069117Andy Hung{ 89523ef1b379caa5e641367f115d67080ed35069117Andy Hung static const float scale = 1. / (float)(1UL << 7); 89623ef1b379caa5e641367f115d67080ed35069117Andy Hung 89723ef1b379caa5e641367f115d67080ed35069117Andy Hung return ((int)uval - 128) * scale; 89823ef1b379caa5e641367f115d67080ed35069117Andy Hung} 89923ef1b379caa5e641367f115d67080ed35069117Andy Hung 9003e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 9013e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a packed 24bit Q0.23 value stored native-endian in a uint8_t ptr 902e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to a signed fixed-point 32 bit integer Q0.31 value. The output Q0.31 range 903e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * is [0x80000000, 0x7fffff00] for the fixed-point range [0x800000, 0x7fffff]. 904e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Even though the output range is limited on the positive side, there is no 905e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * DC offset on the output, if the input has no DC offset. 906e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 907e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Avoid relying on the limited output range, as future implementations may go 908e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to full range. 909e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 910e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline int32_t i32_from_p24(const uint8_t *packed24) 911e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 912e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* convert to 32b */ 913e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return (packed24[0] << 8) | (packed24[1] << 16) | (packed24[2] << 24); 914e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 915e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 9163e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 9173e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a 32-bit Q0.31 value to single-precision floating-point. 9182c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The output float range is [-1.0, 1.0] for the fixed-point range 9192c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * [0x80000000, 0x7fffffff]. 9202c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * 9212c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding may occur in the least significant 8 bits for large fixed point 9222c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * values due to storage into the 24-bit floating-point significand. 9232c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding will be to nearest, ties to even. 9242c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 9252c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungstatic inline float float_from_i32(int32_t ival) 9262c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung{ 9272c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float scale = 1. / (float)(1UL << 31); 9282c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 9292c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return ival * scale; 9302c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung} 9312c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 9323e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 9333e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a packed 24bit Q0.23 value stored native endian in a uint8_t ptr 934e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to single-precision floating-point. The output float range is [-1.0, 1.0) 935e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for the fixed-point range [0x800000, 0x7fffff]. 936e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 937e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * There is no rounding, the conversion and representation is exact. 938e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 939e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline float float_from_p24(const uint8_t *packed24) 940e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 9412c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return float_from_i32(i32_from_p24(packed24)); 942e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 943e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 9443e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten/** 9453e576806bc3c161e4e81e4ab19eaea2fb0ca6b72Glenn Kasten * Convert a 24-bit Q8.23 value to single-precision floating-point. 946d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The nominal output float range is [-1.0, 1.0) for the fixed-point 947d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * range [0xff800000, 0x007fffff]. The maximum float range is [-256.0, 256.0). 948d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * 949d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * There is no rounding in the nominal range, the conversion and representation 950d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * is exact. For values outside the nominal range, rounding is to nearest, ties to even. 951d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 952d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungstatic inline float float_from_q8_23(int32_t ival) 953d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung{ 954d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung static const float scale = 1. / (float)(1UL << 23); 955d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 956d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung return ival * scale; 957d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung} 958d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 959632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 960632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Multiply-accumulate 16-bit terms with 32-bit result: return a + in*v. 961632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 962632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 963632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulAdd(int16_t in, int16_t v, int32_t a) 964632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 965632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 966632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 967632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlabb %[out], %[in], %[v], %[a] \n" 968632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 969632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 970632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 971632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 972632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 973632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + in * (int32_t)v; 974632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 975632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 976632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 977632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 978632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Multiply 16-bit terms with 32-bit result: return in*v. 979632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 980632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 981632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mul(int16_t in, int16_t v) 982632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 983632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 984632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 985632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smulbb %[out], %[in], %[v] \n" 986632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 987632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [in]"%r"(in), [v]"r"(v) 988632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 989632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 990632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 991632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return in * (int32_t)v; 992632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 993632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 994632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 995632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 996632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Similar to mulAdd, but the 16-bit terms are extracted from a 32-bit interleaved stereo pair. 997632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 998632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 999632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a) 1000632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 1001632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 1002632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 1003632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 1004632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n" 1005632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 1006632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) 1007632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 1008632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 1009632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n" 1010632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 1011632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) 1012632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 1013632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 1014632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 1015632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 1016632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 1017632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + (int16_t)(inRL&0xFFFF) * (int16_t)(vRL&0xFFFF); 1018632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 1019632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + (int16_t)(inRL>>16) * (int16_t)(vRL>>16); 1020632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 1021632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 1022632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 1023632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 1024632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 1025632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Similar to mul, but the 16-bit terms are extracted from a 32-bit interleaved stereo pair. 1026632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 1027632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 1028632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulRL(int left, uint32_t inRL, uint32_t vRL) 1029632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 1030632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 1031632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 1032632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 1033632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smulbb %[out], %[inRL], %[vRL] \n" 1034632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 1035632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL) 1036632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 1037632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 1038632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smultt %[out], %[inRL], %[vRL] \n" 1039632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 1040632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL) 1041632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 1042632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 1043632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 1044632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 1045632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 1046632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return (int16_t)(inRL&0xFFFF) * (int16_t)(vRL&0xFFFF); 1047632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 1048632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return (int16_t)(inRL>>16) * (int16_t)(vRL>>16); 1049632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 1050632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 1051632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 1052632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 105331e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** \cond */ 1054632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten__END_DECLS 105531e924f383940e7632273109674b36e1d1faba7fGlenn Kasten/** \endcond */ 1056632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 1057632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif // ANDROID_AUDIO_PRIMITIVES_H 1058