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 24632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten__BEGIN_DECLS 25632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 26e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* The memcpy_* conversion routines are designed to work in-place on same dst as src 27e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * buffers only if the types shrink on copy, with the exception of memcpy_to_i16_from_u8(). 28e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * This allows the loops to go upwards for faster cache access (and may be more flexible 29e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for future optimization later). 30e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 31e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 32632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 33632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Dither and clamp pairs of 32-bit input samples (sums) to 16-bit output samples (out). 34d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * Each 32-bit input sample can be viewed as a signed fixed-point Q19.12 of which the 35d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * .12 fraction bits are dithered and the 19 integer bits are clamped to signed 16 bits. 36d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * Alternatively the input can be viewed as Q4.27, of which the lowest .12 of the fraction 37d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * is dithered and the remaining fraction is converted to the output Q.15, with clamping 38d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * on the 4 integer guard bits. 39d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * 40632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * For interleaved stereo, c is the number of sample pairs, 41632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * and out is an array of interleaved pairs of 16-bit samples per channel. 42632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * For mono, c is the number of samples / 2, and out is an array of 16-bit samples. 43632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * The name "dither" is a misnomer; the current implementation does not actually dither 44632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * but uses truncation. This may change. 457ef795a9d1ac0f3f464e0e7a54aeca00bf94215bGlenn Kasten * The out and sums buffers must either be completely separate (non-overlapping), or 467ef795a9d1ac0f3f464e0e7a54aeca00bf94215bGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 47632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 48632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenvoid ditherAndClamp(int32_t* out, const int32_t *sums, size_t c); 49632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 50ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten/* Expand and copy samples from unsigned 8-bit offset by 0x80 to signed 16-bit. 51ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * Parameters: 52ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * dst Destination buffer 53ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * src Source buffer 54ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * count Number of samples to copy 55ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 56ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 57ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten */ 58ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kastenvoid memcpy_to_i16_from_u8(int16_t *dst, const uint8_t *src, size_t count); 59ddb2e930bef3d1be1627c613fb8f3df848166ac7Glenn Kasten 6078da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten/* Shrink and copy samples from signed 16-bit to unsigned 8-bit offset by 0x80. 6178da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * Parameters: 6278da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * dst Destination buffer 6378da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * src Source buffer 6478da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * count Number of samples to copy 6578da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 6678da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 6778da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 6878da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten */ 6978da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kastenvoid memcpy_to_u8_from_i16(uint8_t *dst, const int16_t *src, size_t count); 7078da2acdd7aa14fe9920d1ad3074e445332de27dGlenn Kasten 715d43605288f444eb30999334642253283941fb3dGlenn Kasten/* Shrink and copy samples from signed 32-bit fixed-point Q0.31 to signed 16-bit Q0.15. 725d43605288f444eb30999334642253283941fb3dGlenn Kasten * Parameters: 735d43605288f444eb30999334642253283941fb3dGlenn Kasten * dst Destination buffer 745d43605288f444eb30999334642253283941fb3dGlenn Kasten * src Source buffer 755d43605288f444eb30999334642253283941fb3dGlenn Kasten * count Number of samples to copy 765d43605288f444eb30999334642253283941fb3dGlenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 775d43605288f444eb30999334642253283941fb3dGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 785d43605288f444eb30999334642253283941fb3dGlenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 795d43605288f444eb30999334642253283941fb3dGlenn Kasten */ 805d43605288f444eb30999334642253283941fb3dGlenn Kastenvoid memcpy_to_i16_from_i32(int16_t *dst, const int32_t *src, size_t count); 815d43605288f444eb30999334642253283941fb3dGlenn Kasten 825d43605288f444eb30999334642253283941fb3dGlenn Kasten/* Shrink and copy samples from single-precision floating-point to signed 16-bit. 83db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Each float should be in the range -1.0 to 1.0. Values outside that range are clamped, 8465b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hung * refer to clamp16_from_float(). 855d43605288f444eb30999334642253283941fb3dGlenn Kasten * Parameters: 865d43605288f444eb30999334642253283941fb3dGlenn Kasten * dst Destination buffer 875d43605288f444eb30999334642253283941fb3dGlenn Kasten * src Source buffer 885d43605288f444eb30999334642253283941fb3dGlenn Kasten * count Number of samples to copy 895d43605288f444eb30999334642253283941fb3dGlenn Kasten * The destination and source buffers must either be completely separate (non-overlapping), or 905d43605288f444eb30999334642253283941fb3dGlenn Kasten * they must both start at the same address. Partially overlapping buffers are not supported. 915d43605288f444eb30999334642253283941fb3dGlenn Kasten * The conversion is done by truncation, without dithering, so it loses resolution. 925d43605288f444eb30999334642253283941fb3dGlenn Kasten */ 935d43605288f444eb30999334642253283941fb3dGlenn Kastenvoid memcpy_to_i16_from_float(int16_t *dst, const float *src, size_t count); 945d43605288f444eb30999334642253283941fb3dGlenn Kasten 95d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung/* Copy samples from signed fixed-point 32-bit Q4.27 to single-precision floating-point. 96aecb15eb579434bbc980892b3707374340e00138Andy Hung * The nominal output float range is [-1.0, 1.0] if the fixed-point range is 97aecb15eb579434bbc980892b3707374340e00138Andy Hung * [0xf8000000, 0x07ffffff]. The full float range is [-16.0, 16.0]. Note the closed range 98d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung * at 1.0 and 16.0 is due to rounding on conversion to float. See float_from_q4_27() for details. 99aecb15eb579434bbc980892b3707374340e00138Andy Hung * Parameters: 100aecb15eb579434bbc980892b3707374340e00138Andy Hung * dst Destination buffer 101aecb15eb579434bbc980892b3707374340e00138Andy Hung * src Source buffer 102aecb15eb579434bbc980892b3707374340e00138Andy Hung * count Number of samples to copy 103aecb15eb579434bbc980892b3707374340e00138Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 104aecb15eb579434bbc980892b3707374340e00138Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 105aecb15eb579434bbc980892b3707374340e00138Andy Hung */ 106b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungvoid memcpy_to_float_from_q4_27(float *dst, const int32_t *src, size_t count); 107aecb15eb579434bbc980892b3707374340e00138Andy Hung 108e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Copy samples from signed fixed-point 16 bit Q0.15 to single-precision floating-point. 109e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range [0x8000, 0x7fff]. 110e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * No rounding is needed as the representation is exact. 111e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Parameters: 112e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * dst Destination buffer 113e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * src Source buffer 114e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * count Number of samples to copy 115e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must be completely separate. 116e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 117e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_float_from_i16(float *dst, const int16_t *src, size_t count); 118e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 119e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Copy samples from signed fixed-point packed 24 bit Q0.23 to single-precision floating-point. 120e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The packed 24 bit input is stored in native endian format in a uint8_t byte array. 121e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range [0x800000, 0x7fffff]. 122e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * No rounding is needed as the representation is exact. 123e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Parameters: 124e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * dst Destination buffer 125e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * src Source buffer 126e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * count Number of samples to copy 127e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must be completely separate. 128e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 129e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_float_from_p24(float *dst, const uint8_t *src, size_t count); 130e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 131e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Copy samples from signed fixed-point packed 24 bit Q0.23 to signed fixed point 16 bit Q0.15. 132e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The packed 24 bit output is stored in native endian format in a uint8_t byte array. 133e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The data is truncated without rounding. 134e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Parameters: 135e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * dst Destination buffer 136e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * src Source buffer 137e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * count Number of samples to copy 138e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 139e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 140e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 141e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_i16_from_p24(int16_t *dst, const uint8_t *src, size_t count); 142e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 143e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Copy samples from signed fixed point 16 bit Q0.15 to signed fixed-point packed 24 bit Q0.23. 144a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 145e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output data range is [0x800000, 0x7fff00] (not full). 146e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Nevertheless there is no DC offset on the output, if the input has no DC offset. 147e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Parameters: 148e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * dst Destination buffer 149e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * src Source buffer 150e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * count Number of samples to copy 151e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must be completely separate. 152e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 153e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_p24_from_i16(uint8_t *dst, const int16_t *src, size_t count); 154e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 155e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Copy samples from single-precision floating-point to signed fixed-point packed 24 bit Q0.23. 156a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 157e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The data is clamped and rounded to nearest, ties away from zero. See clamp24_from_float() 158e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for details. 159e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Parameters: 160e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * dst Destination buffer 161e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * src Source buffer 162e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * count Number of samples to copy 163e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 164e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 165e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 166e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungvoid memcpy_to_p24_from_float(uint8_t *dst, const float *src, size_t count); 167e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 168eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten/* Copy samples from signed fixed-point 32-bit Q8.23 to signed fixed-point packed 24 bit Q0.23. 169a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten * The packed 24 bit output is assumed to be a native-endian uint8_t byte array. 170eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * The data is clamped to the range is [0x800000, 0x7fffff]. 171eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * Parameters: 172eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * dst Destination buffer 173eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * src Source buffer 174eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * count Number of samples to copy 175eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * The destination and source buffers must be completely separate. 176eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten */ 177eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kastenvoid memcpy_to_p24_from_q8_23(uint8_t *dst, const int32_t *src, size_t count); 178eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten 179d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung/* Copy samples from signed fixed point 16-bit Q0.15 to signed fixed-point 32-bit Q8.23. 180d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The output data range is [0xff800000, 0x007fff00] at intervals of 0x100. 181d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * Parameters: 182d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * dst Destination buffer 183d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * src Source buffer 184d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * count Number of samples to copy 185d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must be completely separate. 186d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 187d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_q8_23_from_i16(int32_t *dst, const int16_t *src, size_t count); 188d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 189d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung/* Copy samples from single-precision floating-point to signed fixed-point 32-bit Q8.23. 190d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * This copy will clamp the Q8.23 representation to [0xff800000, 0x007fffff] even though there 191d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * are guard bits available. Fractional lsb is rounded to nearest, ties away from zero. 192d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * See clamp24_from_float() for details. 193d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * Parameters: 194d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * dst Destination buffer 195d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * src Source buffer 196d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * count Number of samples to copy 197d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 198d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 199d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 200d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_q8_23_from_float_with_clamp(int32_t *dst, const float *src, size_t count); 201d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 202b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung/* Copy samples from single-precision floating-point to signed fixed-point 32-bit Q4.27. 203b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * The conversion will use the full available Q4.27 range, including guard bits. 204b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Fractional lsb is rounded to nearest, ties away from zero. 205b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * See clampq4_27_from_float() for details. 206b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Parameters: 207b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * dst Destination buffer 208b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * src Source buffer 209b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * count Number of samples to copy 210b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 211b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 212b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 213b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungvoid memcpy_to_q4_27_from_float(int32_t *dst, const float *src, size_t count); 214b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 215d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung/* Copy samples from signed fixed-point 32-bit Q8.23 to signed fixed point 16-bit Q0.15. 216d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The data is clamped, and truncated without rounding. 217d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * Parameters: 218d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * dst Destination buffer 219d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * src Source buffer 220d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * count Number of samples to copy 221d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 222d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 223d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 224d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_i16_from_q8_23(int16_t *dst, const int32_t *src, size_t count); 225d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 226d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung/* Copy samples from signed fixed-point 32-bit Q8.23 to single-precision floating-point. 227d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The nominal output float range is [-1.0, 1.0) for the fixed-point 228d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * range [0xff800000, 0x007fffff]. The maximum output float range is [-256.0, 256.0). 229d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * No rounding is needed as the representation is exact for nominal values. 230d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * Rounding for overflow values is to nearest, ties to even. 231d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * Parameters: 232d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * dst Destination buffer 233d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * src Source buffer 234d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * count Number of samples to copy 235d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 236d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 237d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 238d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungvoid memcpy_to_float_from_q8_23(float *dst, const int32_t *src, size_t count); 239d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 2402c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Copy samples from signed fixed point 16-bit Q0.15 to signed fixed-point 32-bit Q0.31. 2412c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The output data range is [0x80000000, 0x7fff0000] at intervals of 0x10000. 2422c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Parameters: 2432c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * dst Destination buffer 2442c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * src Source buffer 2452c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * count Number of samples to copy 2462c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The destination and source buffers must be completely separate. 2472c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 2482c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungvoid memcpy_to_i32_from_i16(int32_t *dst, const int16_t *src, size_t count); 2492c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 2502c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Copy samples from single-precision floating-point to signed fixed-point 32-bit Q0.31. 2512c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * If rounding is needed on truncation, the fractional lsb is rounded to nearest, 2522c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * ties away from zero. See clamp32_from_float() for details. 2532c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Parameters: 2542c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * dst Destination buffer 2552c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * src Source buffer 2562c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * count Number of samples to copy 2572c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 2582c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 2592c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 2602c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungvoid memcpy_to_i32_from_float(int32_t *dst, const float *src, size_t count); 2612c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 2622c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Copy samples from signed fixed-point 32-bit Q0.31 to single-precision floating-point. 2632c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The float range is [-1.0, 1.0] for the fixed-point range [0x80000000, 0x7fffffff]. 2642c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding is done according to float_from_i32(). 2652c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Parameters: 2662c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * dst Destination buffer 2672c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * src Source buffer 2682c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * count Number of samples to copy 2692c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The destination and source buffers must either be completely separate (non-overlapping), or 2702c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * they must both start at the same address. Partially overlapping buffers are not supported. 2712c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 2722c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungvoid memcpy_to_float_from_i32(float *dst, const int32_t *src, size_t count); 2732c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 2747a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten/* Downmix pairs of interleaved stereo input 16-bit samples to mono output 16-bit samples. 2757a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * Parameters: 2767a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * dst Destination buffer 2777a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * src Source buffer 2787a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * count Number of stereo frames to downmix 2797a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * The destination and source buffers must be completely separate (non-overlapping). 2807a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * The current implementation truncates the sum rather than dither, but this may change. 2817a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten */ 2827a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kastenvoid downmix_to_mono_i16_from_stereo_i16(int16_t *dst, const int16_t *src, size_t count); 2837a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten 2847a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten/* Upmix mono input 16-bit samples to pairs of interleaved stereo output 16-bit samples by 2857a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * duplicating. 2867a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * Parameters: 2877a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * dst Destination buffer 2887a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * src Source buffer 2897a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * count Number of mono samples to upmix 2907a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten * The destination and source buffers must be completely separate (non-overlapping). 2917a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten */ 2927a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kastenvoid upmix_to_stereo_i16_from_mono_i16(int16_t *dst, const int16_t *src, size_t count); 2937a0bacaf9634d6bf0abbea9608fb15e94a675358Glenn Kasten 294eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten/* Return the total number of non-zero 32-bit samples */ 295eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroMono32(const int32_t *samples, size_t count); 296eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 297eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten/* Return the total number of non-zero 16-bit samples */ 298eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroMono16(const int16_t *samples, size_t count); 299eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 300eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten/* Return the total number of non-zero stereo frames, where a frame is considered non-zero 301eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten * if either of its constituent 32-bit samples is non-zero 302eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten */ 303eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroStereo32(const int32_t *frames, size_t count); 304eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 305eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten/* Return the total number of non-zero stereo frames, where a frame is considered non-zero 306eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten * if either of its constituent 16-bit samples is non-zero 307eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten */ 308eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kastensize_t nonZeroStereo16(const int16_t *frames, size_t count); 309eb247dfc917ebfb02e164cdd82ce5fa2c0815369Glenn Kasten 3103af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung/* Copy frames, selecting source samples based on a source channel mask to fit 3113af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * the destination channel mask. Unmatched channels in the destination channel mask 3123af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * are zero filled. Unmatched channels in the source channel mask are dropped. 3133af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Channels present in the channel mask are represented by set bits in the 3143af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * uint32_t value and are matched without further interpretation. 3153af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Parameters: 3163af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * dst Destination buffer 3173af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * dst_mask Bit mask corresponding to destination channels present 3183af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * src Source buffer 3193af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * src_mask Bit mask corresponding to source channels present 3203af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * sample_size Size of each sample in bytes. Must be 1, 2, 3, or 4. 3213af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * count Number of frames to copy 3223af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The destination and source buffers must be completely separate (non-overlapping). 3233af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * If the sample size is not in range, the function will abort. 3243af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung */ 3253af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungvoid memcpy_by_channel_mask(void *dst, uint32_t dst_mask, 3263af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const void *src, uint32_t src_mask, size_t sample_size, size_t count); 3273af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3283af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung/* Copy frames, selecting source samples based on an index array (idxary). 3293af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The idxary[] consists of dst_channels number of elements. 3303af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The ith element if idxary[] corresponds the ith destination channel. 3313af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * A non-negative value is the channel index in the source frame. 3323af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * A negative index (-1) represents filling with 0. 3333af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 3343af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Example: Swapping L and R channels for stereo streams 3353af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[0] = 1; 3363af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[1] = 0; 3373af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 3383af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Example: Copying a mono source to the front center 5.1 channel 3393af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[0] = -1; 3403af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[1] = -1; 3413af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[2] = 0; 3423af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[3] = -1; 3433af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[4] = -1; 3443af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary[5] = -1; 3453af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 3463af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * This copy allows swizzling of channels or replication of channels. 3473af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 3483af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Parameters: 3493af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * dst Destination buffer 3503af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * dst_channels Number of destination channels per frame 3513af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * src Source buffer 3523af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * src_channels Number of source channels per frame 3533af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary Array of indices representing channels in the source frame 3543af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * sample_size Size of each sample in bytes. Must be 1, 2, 3, or 4. 3553af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * count Number of frames to copy 3563af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * The destination and source buffers must be completely separate (non-overlapping). 3573af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * If the sample size is not in range, the function will abort. 3583af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung */ 3593af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungvoid memcpy_by_index_array(void *dst, uint32_t dst_channels, 3603af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const void *src, uint32_t src_channels, 3613af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung const int8_t *idxary, size_t sample_size, size_t count); 3623af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 3633af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung/* Prepares an index array (idxary) from channel masks, which can be later 3643af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * used by memcpy_by_index_array(). Returns the number of array elements required. 3653af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * This may be greater than idxcount, so the return value should be checked 3663af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * if idxary size is less than 32. Note that idxary is a caller allocated array 3673af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * of at least as many channels as present in the dst_mask. 3683af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Channels present in the channel mask are represented by set bits in the 3693af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * uint32_t value and are matched without further interpretation. 3703af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * 3713af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * Parameters: 3723af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxary Updated array of indices of channels in the src frame for the dst frame 3733af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * idxcount Number of caller allocated elements in idxary 3743af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * dst_mask Bit mask corresponding to destination channels present 3753af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung * src_mask Bit mask corresponding to source channels present 3763af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung */ 3773af2af2518dc5534c94285e77d39d0fc729ed917Andy Hungsize_t memcpy_by_index_array_initialization(int8_t *idxary, size_t idxcount, 3783af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung uint32_t dst_mask, uint32_t src_mask); 3793af2af2518dc5534c94285e77d39d0fc729ed917Andy Hung 380632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 381632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Clamp (aka hard limit or clip) a signed 32-bit sample to 16-bit range. 382632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 383632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline int16_t clamp16(int32_t sample) 384632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 385632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if ((sample>>15) ^ (sample>>31)) 386632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten sample = 0x7FFF ^ (sample>>31); 387632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return sample; 388632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 389632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 390db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung/* 391db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Convert a IEEE 754 single precision float [-1.0, 1.0) to int16_t [-32768, 32767] 392db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * with clamping. Note the open bound at 1.0, values within 1/65536 of 1.0 map 393db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * to 32767 instead of 32768 (early clamping due to the smaller positive integer subrange). 394db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * 395db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -32768 and 32767, 396db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * including -Inf and +Inf. NaN will generally be treated either as -32768 or 32767, 397db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * depending on the sign bit inside NaN (whose representation is not unique). 398db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Nevertheless, strictly speaking, NaN behavior should be considered undefined. 399db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * 400db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Rounding of 0.5 lsb is to even (default for IEEE 754). 401db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 40265b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hungstatic inline int16_t clamp16_from_float(float f) 403db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung{ 404db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* Offset is used to expand the valid range of [-1.0, 1.0) into the 16 lsbs of the 405db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * floating point significand. The normal shift is 3<<22, but the -15 offset 406db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * is used to multiply by 32768. 407db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 408db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const float offset = (float)(3 << (22 - 15)); 409db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* zero = (0x10f << 22) = 0x43c00000 (not directly used) */ 410db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const int32_t limneg = (0x10f << 22) /*zero*/ - 32768; /* 0x43bf8000 */ 411db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const int32_t limpos = (0x10f << 22) /*zero*/ + 32767; /* 0x43c07fff */ 412db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 413db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung union { 414db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung float f; 415db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung int32_t i; 416db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung } u; 417db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 418db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.f = f + offset; /* recenter valid range */ 419db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* Now the valid range is represented as integers between [limneg, limpos]. 420db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Clamp using the fact that float representation (as an integer) is an ordered set. 421db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 422db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung if (u.i < limneg) 423db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.i = -32768; 424db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung else if (u.i > limpos) 425db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.i = 32767; 426db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung return u.i; /* Return lower 16 bits, the part of interest in the significand. */ 427db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung} 428db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 429e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a single-precision floating point value to a Q0.23 integer value, stored in a 430e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 32 bit signed integer (technically stored as Q8.23, but clamped to Q0.23). 431e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 432e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Rounds to nearest, ties away from 0. 433e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 434e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -8388608 and 8388607, 435e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 436e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * depending on hardware and future implementation of this function. 437e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 438e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline int32_t clamp24_from_float(float f) 439e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 440e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float scale = (float)(1 << 23); 441e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float limpos = 0x7fffff / scale; 442e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float limneg = -0x800000 / scale; 443e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 444e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung if (f <= limneg) { 445e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return -0x800000; 446e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung } else if (f >= limpos) { 447e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return 0x7fffff; 448e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung } 449e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung f *= scale; 450e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* integer conversion is through truncation (though int to float is not). 451e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * ensure that we round to nearest, ties away from 0. 452e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 453e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 454e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 455e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 456eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten/* Convert a signed fixed-point 32-bit Q8.23 value to a Q0.23 integer value, 457eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * stored in a 32-bit signed integer (technically stored as Q8.23, but clamped to Q0.23). 458eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * 459eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * Values outside the range [-0x800000, 0x7fffff] are clamped to that range. 460eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten */ 461eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kastenstatic inline int32_t clamp24_from_q8_23(int32_t ival) 462eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten{ 463eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten static const int32_t limpos = 0x7fffff; 464eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten static const int32_t limneg = -0x800000; 465eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten if (ival < limneg) { 466eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return limneg; 467eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } else if (ival > limpos) { 468eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return limpos; 469eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } else { 470eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return ival; 471eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } 472eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten} 473eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten 474b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung/* Convert a single-precision floating point value to a Q4.27 integer value. 475b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Rounds to nearest, ties away from 0. 476b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * 477b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Values outside the range [-16.0, 16.0) are properly clamped to -2147483648 and 2147483647, 478b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 479b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * depending on hardware and future implementation of this function. 480b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 481b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungstatic inline int32_t clampq4_27_from_float(float f) 482b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung{ 483b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float scale = (float)(1UL << 27); 484b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float limpos = 16.; 485b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float limneg = -16.; 486b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 487b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung if (f <= limneg) { 488b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return -0x80000000; /* or 0x80000000 */ 489b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } else if (f >= limpos) { 490b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return 0x7fffffff; 491b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } 492b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung f *= scale; 493b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung /* integer conversion is through truncation (though int to float is not). 494b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * ensure that we round to nearest, ties away from 0. 495b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 496b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 497b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung} 498b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 4992c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Convert a single-precision floating point value to a Q0.31 integer value. 5002c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounds to nearest, ties away from 0. 5012c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * 5022c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -2147483648 and 2147483647, 5032c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 5042c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * depending on hardware and future implementation of this function. 5052c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 5062c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungstatic inline int32_t clamp32_from_float(float f) 5072c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung{ 5082c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float scale = (float)(1UL << 31); 5092c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float limpos = 1.; 5102c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float limneg = -1.; 5112c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 5122c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung if (f <= limneg) { 513b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return -0x80000000; /* or 0x80000000 */ 5142c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung } else if (f >= limpos) { 5152c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return 0x7fffffff; 5162c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung } 5172c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung f *= scale; 5182c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung /* integer conversion is through truncation (though int to float is not). 5192c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * ensure that we round to nearest, ties away from 0. 5202c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 5212c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 5222c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung} 5232c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 524d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung/* Convert a signed fixed-point 32-bit Q4.27 value to single-precision floating-point. 52542605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * The nominal output float range is [-1.0, 1.0] if the fixed-point range is 52642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * [0xf8000000, 0x07ffffff]. The full float range is [-16.0, 16.0]. 52742605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * 52842605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * Note the closed range at 1.0 and 16.0 is due to rounding on conversion to float. 52942605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * In more detail: if the fixed-point integer exceeds 24 bit significand of single 53042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * precision floating point, the 0.5 lsb in the significand conversion will round 53142605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * towards even, as per IEEE 754 default. 53242605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung */ 533d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hungstatic inline float float_from_q4_27(int32_t ival) 53442605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung{ 535d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung /* The scale factor is the reciprocal of the fractional bits. 53642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * 53742605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * Since the scale factor is a power of 2, the scaling is exact, and there 53842605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * is no rounding due to the multiplication - the bit pattern is preserved. 53942605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * However, there may be rounding due to the fixed-point to float conversion, 54042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * as described above. 54142605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung */ 542d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung static const float scale = 1. / (float)(1UL << 27); 54342605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung 54442605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung return ival * scale; 54542605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung} 54642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung 547de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung/* Convert an unsigned fixed-point 32-bit U4.28 value to single-precision floating-point. 548de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * The nominal output float range is [0.0, 1.0] if the fixed-point range is 549de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * [0x00000000, 0x10000000]. The full float range is [0.0, 16.0]. 550de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * 551de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Note the closed range at 1.0 and 16.0 is due to rounding on conversion to float. 552de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * In more detail: if the fixed-point integer exceeds 24 bit significand of single 553de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * precision floating point, the 0.5 lsb in the significand conversion will round 554de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * towards even, as per IEEE 754 default. 555de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 556de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline float float_from_u4_28(uint32_t uval) 557de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 558de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = 1. / (float)(1UL << 28); 559de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 560de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return uval * scale; 561de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 562de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 563de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung/* Convert an unsigned fixed-point 16-bit U4.12 value to single-precision floating-point. 564de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * The nominal output float range is [0.0, 1.0] if the fixed-point range is 565de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * [0x0000, 0x1000]. The full float range is [0.0, 16.0). 566de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 567de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline float float_from_u4_12(uint16_t uval) 568de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 569de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = 1. / (float)(1UL << 12); 570de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 571de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return uval * scale; 572de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 573de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 574de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung/* Convert a single-precision floating point value to a U4.28 integer value. 575de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Rounds to nearest, ties away from 0. 576de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * 577de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Values outside the range [0, 16.0] are properly clamped to [0, 4294967295] 578de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 579de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * depending on hardware and future implementation of this function. 580de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 581de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline uint32_t u4_28_from_float(float f) 582de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 583de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = (float)(1 << 28); 584de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float limpos = 0xffffffffUL / scale; 585de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 586de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung if (f <= 0.) { 587de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0; 588de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } else if (f >= limpos) { 589de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0xffffffff; 590de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } 591de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung /* integer conversion is through truncation (though int to float is not). 592de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * ensure that we round to nearest, ties away from 0. 593de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 594de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return f * scale + 0.5; 595de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 596de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 597de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung/* Convert a single-precision floating point value to a U4.12 integer value. 598de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Rounds to nearest, ties away from 0. 599de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * 600de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * Values outside the range [0, 16.0) are properly clamped to [0, 65535] 601de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 602de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * depending on hardware and future implementation of this function. 603de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 604de9a62b5a163e343a1ed8e1068741e227122d510Andy Hungstatic inline uint16_t u4_12_from_float(float f) 605de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung{ 606de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float scale = (float)(1 << 12); 607de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung static const float limpos = 0xffff / scale; 608de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 609de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung if (f <= 0.) { 610de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0; 611de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } else if (f >= limpos) { 612de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return 0xffff; 613de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung } 614de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung /* integer conversion is through truncation (though int to float is not). 615de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung * ensure that we round to nearest, ties away from 0. 616de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung */ 617de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung return f * scale + 0.5; 618de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung} 619de9a62b5a163e343a1ed8e1068741e227122d510Andy Hung 620e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a signed fixed-point 16-bit Q0.15 value to single-precision floating-point. 621e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range 622e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * [0x8000, 0x7fff]. 623e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 624e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * There is no rounding, the conversion and representation is exact. 625e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 626e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline float float_from_i16(int16_t ival) 627e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 628e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* The scale factor is the reciprocal of the nominal 16 bit integer 629e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * half-sided range (32768). 630e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 631e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Since the scale factor is a power of 2, the scaling is exact, and there 632e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * is no rounding due to the multiplication - the bit pattern is preserved. 633e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 634e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float scale = 1. / (float)(1UL << 15); 635e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 636e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return ival * scale; 637e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 638e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 639a56b2c49166e08a3a13506a7c1832b739d5db168Glenn Kasten/* Convert a packed 24bit Q0.23 value stored native-endian in a uint8_t ptr 640e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to a signed fixed-point 32 bit integer Q0.31 value. The output Q0.31 range 641e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * is [0x80000000, 0x7fffff00] for the fixed-point range [0x800000, 0x7fffff]. 642e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Even though the output range is limited on the positive side, there is no 643e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * DC offset on the output, if the input has no DC offset. 644e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 645e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Avoid relying on the limited output range, as future implementations may go 646e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to full range. 647e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 648e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline int32_t i32_from_p24(const uint8_t *packed24) 649e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 650e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* convert to 32b */ 6510d17cca623b113a4ef6ae00f019e169d96d45c91Andy Hung#if defined(HAVE_BIG_ENDIAN) == defined(HAVE_LITTLE_ENDIAN) 6520d17cca623b113a4ef6ae00f019e169d96d45c91Andy Hung /* check to see if we have exactly one or the other android endian flags set. */ 6530d17cca623b113a4ef6ae00f019e169d96d45c91Andy Hung#error "Either HAVE_LITTLE_ENDIAN or HAVE_BIG_ENDIAN must be defined" 6540d17cca623b113a4ef6ae00f019e169d96d45c91Andy Hung#elif defined(HAVE_BIG_ENDIAN) 655e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return (packed24[2] << 8) | (packed24[1] << 16) | (packed24[0] << 24); 6560d17cca623b113a4ef6ae00f019e169d96d45c91Andy Hung#else /* HAVE_LITTLE_ENDIAN */ 657e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return (packed24[0] << 8) | (packed24[1] << 16) | (packed24[2] << 24); 658e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#endif 659e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 660e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 6612c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Convert a 32-bit Q0.31 value to single-precision floating-point. 6622c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The output float range is [-1.0, 1.0] for the fixed-point range 6632c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * [0x80000000, 0x7fffffff]. 6642c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * 6652c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding may occur in the least significant 8 bits for large fixed point 6662c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * values due to storage into the 24-bit floating-point significand. 6672c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding will be to nearest, ties to even. 6682c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 6692c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungstatic inline float float_from_i32(int32_t ival) 6702c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung{ 6712c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float scale = 1. / (float)(1UL << 31); 6722c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 6732c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return ival * scale; 6742c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung} 6752c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 676e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a packed 24bit Q0.23 value stored native endian in a uint8_t ptr 677e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to single-precision floating-point. The output float range is [-1.0, 1.0) 678e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for the fixed-point range [0x800000, 0x7fffff]. 679e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 680e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * There is no rounding, the conversion and representation is exact. 681e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 682e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline float float_from_p24(const uint8_t *packed24) 683e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 6842c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return float_from_i32(i32_from_p24(packed24)); 685e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 686e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 687d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung/* Convert a 24-bit Q8.23 value to single-precision floating-point. 688d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The nominal output float range is [-1.0, 1.0) for the fixed-point 689d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * range [0xff800000, 0x007fffff]. The maximum float range is [-256.0, 256.0). 690d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * 691d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * There is no rounding in the nominal range, the conversion and representation 692d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * is exact. For values outside the nominal range, rounding is to nearest, ties to even. 693d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 694d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungstatic inline float float_from_q8_23(int32_t ival) 695d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung{ 696d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung static const float scale = 1. / (float)(1UL << 23); 697d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 698d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung return ival * scale; 699d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung} 700d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 701632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 702632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Multiply-accumulate 16-bit terms with 32-bit result: return a + in*v. 703632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 704632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 705632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulAdd(int16_t in, int16_t v, int32_t a) 706632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 707632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 708632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 709632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlabb %[out], %[in], %[v], %[a] \n" 710632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 711632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 712632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 713632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 714632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 715632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + in * (int32_t)v; 716632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 717632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 718632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 719632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 720632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Multiply 16-bit terms with 32-bit result: return in*v. 721632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 722632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 723632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mul(int16_t in, int16_t v) 724632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 725632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 726632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 727632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smulbb %[out], %[in], %[v] \n" 728632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 729632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [in]"%r"(in), [v]"r"(v) 730632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 731632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 732632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 733632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return in * (int32_t)v; 734632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 735632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 736632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 737632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 738632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Similar to mulAdd, but the 16-bit terms are extracted from a 32-bit interleaved stereo pair. 739632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 740632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 741632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a) 742632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 743632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 744632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 745632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 746632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n" 747632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 748632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) 749632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 750632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 751632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n" 752632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 753632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) 754632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 755632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 756632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 757632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 758632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 759632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + (int16_t)(inRL&0xFFFF) * (int16_t)(vRL&0xFFFF); 760632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 761632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + (int16_t)(inRL>>16) * (int16_t)(vRL>>16); 762632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 763632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 764632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 765632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 766632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 767632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Similar to mul, but the 16-bit terms are extracted from a 32-bit interleaved stereo pair. 768632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 769632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 770632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulRL(int left, uint32_t inRL, uint32_t vRL) 771632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 772632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 773632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 774632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 775632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smulbb %[out], %[inRL], %[vRL] \n" 776632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 777632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL) 778632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 779632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 780632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smultt %[out], %[inRL], %[vRL] \n" 781632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 782632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL) 783632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 784632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 785632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 786632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 787632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 788632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return (int16_t)(inRL&0xFFFF) * (int16_t)(vRL&0xFFFF); 789632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 790632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return (int16_t)(inRL>>16) * (int16_t)(vRL>>16); 791632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 792632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 793632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 794632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 795632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten__END_DECLS 796632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 797632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif // ANDROID_AUDIO_PRIMITIVES_H 798