primitives.h revision eee45154f377e6fc9face02b44ec10a831d98ef7
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. 144e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The packed 24 bit output is assumed to be a little-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. 156e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The packed 24 bit output is assumed to be a little-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. 169eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * The packed 24 bit output is assumed to be a little-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 310632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 311632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Clamp (aka hard limit or clip) a signed 32-bit sample to 16-bit range. 312632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 313632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline int16_t clamp16(int32_t sample) 314632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 315632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if ((sample>>15) ^ (sample>>31)) 316632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten sample = 0x7FFF ^ (sample>>31); 317632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return sample; 318632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 319632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 320db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung/* 321db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Convert a IEEE 754 single precision float [-1.0, 1.0) to int16_t [-32768, 32767] 322db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * with clamping. Note the open bound at 1.0, values within 1/65536 of 1.0 map 323db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * to 32767 instead of 32768 (early clamping due to the smaller positive integer subrange). 324db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * 325db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -32768 and 32767, 326db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * including -Inf and +Inf. NaN will generally be treated either as -32768 or 32767, 327db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * depending on the sign bit inside NaN (whose representation is not unique). 328db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Nevertheless, strictly speaking, NaN behavior should be considered undefined. 329db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * 330db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Rounding of 0.5 lsb is to even (default for IEEE 754). 331db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 33265b5ccd2a7a7c756db2cfa627ac75d17eb0484c2Andy Hungstatic inline int16_t clamp16_from_float(float f) 333db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung{ 334db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* Offset is used to expand the valid range of [-1.0, 1.0) into the 16 lsbs of the 335db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * floating point significand. The normal shift is 3<<22, but the -15 offset 336db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * is used to multiply by 32768. 337db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 338db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const float offset = (float)(3 << (22 - 15)); 339db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* zero = (0x10f << 22) = 0x43c00000 (not directly used) */ 340db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const int32_t limneg = (0x10f << 22) /*zero*/ - 32768; /* 0x43bf8000 */ 341db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung static const int32_t limpos = (0x10f << 22) /*zero*/ + 32767; /* 0x43c07fff */ 342db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 343db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung union { 344db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung float f; 345db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung int32_t i; 346db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung } u; 347db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 348db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.f = f + offset; /* recenter valid range */ 349db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung /* Now the valid range is represented as integers between [limneg, limpos]. 350db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung * Clamp using the fact that float representation (as an integer) is an ordered set. 351db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung */ 352db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung if (u.i < limneg) 353db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.i = -32768; 354db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung else if (u.i > limpos) 355db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung u.i = 32767; 356db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung return u.i; /* Return lower 16 bits, the part of interest in the significand. */ 357db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung} 358db29e694d15e4993ccbacd897bec3b531c3989a9Andy Hung 359e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a single-precision floating point value to a Q0.23 integer value, stored in a 360e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 32 bit signed integer (technically stored as Q8.23, but clamped to Q0.23). 361e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 362e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Rounds to nearest, ties away from 0. 363e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 364e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -8388608 and 8388607, 365e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 366e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * depending on hardware and future implementation of this function. 367e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 368e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline int32_t clamp24_from_float(float f) 369e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 370e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float scale = (float)(1 << 23); 371e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float limpos = 0x7fffff / scale; 372e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float limneg = -0x800000 / scale; 373e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 374e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung if (f <= limneg) { 375e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return -0x800000; 376e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung } else if (f >= limpos) { 377e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return 0x7fffff; 378e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung } 379e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung f *= scale; 380e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* integer conversion is through truncation (though int to float is not). 381e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * ensure that we round to nearest, ties away from 0. 382e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 383e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 384e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 385e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 386eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten/* Convert a signed fixed-point 32-bit Q8.23 value to a Q0.23 integer value, 387eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * stored in a 32-bit signed integer (technically stored as Q8.23, but clamped to Q0.23). 388eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * 389eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten * Values outside the range [-0x800000, 0x7fffff] are clamped to that range. 390eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten */ 391eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kastenstatic inline int32_t clamp24_from_q8_23(int32_t ival) 392eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten{ 393eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten static const int32_t limpos = 0x7fffff; 394eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten static const int32_t limneg = -0x800000; 395eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten if (ival < limneg) { 396eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return limneg; 397eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } else if (ival > limpos) { 398eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return limpos; 399eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } else { 400eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten return ival; 401eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten } 402eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten} 403eee45154f377e6fc9face02b44ec10a831d98ef7Glenn Kasten 404b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung/* Convert a single-precision floating point value to a Q4.27 integer value. 405b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Rounds to nearest, ties away from 0. 406b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * 407b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * Values outside the range [-16.0, 16.0) are properly clamped to -2147483648 and 2147483647, 408b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 409b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * depending on hardware and future implementation of this function. 410b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 411b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hungstatic inline int32_t clampq4_27_from_float(float f) 412b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung{ 413b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float scale = (float)(1UL << 27); 414b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float limpos = 16.; 415b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung static const float limneg = -16.; 416b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 417b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung if (f <= limneg) { 418b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return -0x80000000; /* or 0x80000000 */ 419b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } else if (f >= limpos) { 420b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return 0x7fffffff; 421b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung } 422b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung f *= scale; 423b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung /* integer conversion is through truncation (though int to float is not). 424b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung * ensure that we round to nearest, ties away from 0. 425b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung */ 426b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 427b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung} 428b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung 4292c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Convert a single-precision floating point value to a Q0.31 integer value. 4302c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounds to nearest, ties away from 0. 4312c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * 4322c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Values outside the range [-1.0, 1.0) are properly clamped to -2147483648 and 2147483647, 4332c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * including -Inf and +Inf. NaN values are considered undefined, and behavior may change 4342c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * depending on hardware and future implementation of this function. 4352c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 4362c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungstatic inline int32_t clamp32_from_float(float f) 4372c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung{ 4382c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float scale = (float)(1UL << 31); 4392c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float limpos = 1.; 4402c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float limneg = -1.; 4412c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 4422c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung if (f <= limneg) { 443b878e52fd43ea10f8d45eb29e5901ec1c8fb7278Andy Hung return -0x80000000; /* or 0x80000000 */ 4442c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung } else if (f >= limpos) { 4452c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return 0x7fffffff; 4462c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung } 4472c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung f *= scale; 4482c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung /* integer conversion is through truncation (though int to float is not). 4492c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * ensure that we round to nearest, ties away from 0. 4502c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 4512c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return f > 0 ? f + 0.5 : f - 0.5; 4522c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung} 4532c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 454d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung/* Convert a signed fixed-point 32-bit Q4.27 value to single-precision floating-point. 45542605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * The nominal output float range is [-1.0, 1.0] if the fixed-point range is 45642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * [0xf8000000, 0x07ffffff]. The full float range is [-16.0, 16.0]. 45742605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * 45842605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * Note the closed range at 1.0 and 16.0 is due to rounding on conversion to float. 45942605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * In more detail: if the fixed-point integer exceeds 24 bit significand of single 46042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * precision floating point, the 0.5 lsb in the significand conversion will round 46142605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * towards even, as per IEEE 754 default. 46242605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung */ 463d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hungstatic inline float float_from_q4_27(int32_t ival) 46442605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung{ 465d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung /* The scale factor is the reciprocal of the fractional bits. 46642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * 46742605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * Since the scale factor is a power of 2, the scaling is exact, and there 46842605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * is no rounding due to the multiplication - the bit pattern is preserved. 46942605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * However, there may be rounding due to the fixed-point to float conversion, 47042605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung * as described above. 47142605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung */ 472d2a25cda1c23cc7092824028c49b2bce2cbb4ca2Andy Hung static const float scale = 1. / (float)(1UL << 27); 47342605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung 47442605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung return ival * scale; 47542605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung} 47642605b3647a59243f15a4f1756d70dc69cd1db6aAndy Hung 477e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a signed fixed-point 16-bit Q0.15 value to single-precision floating-point. 478e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * The output float range is [-1.0, 1.0) for the fixed-point range 479e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * [0x8000, 0x7fff]. 480e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 481e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * There is no rounding, the conversion and representation is exact. 482e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 483e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline float float_from_i16(int16_t ival) 484e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 485e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* The scale factor is the reciprocal of the nominal 16 bit integer 486e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * half-sided range (32768). 487e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 488e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Since the scale factor is a power of 2, the scaling is exact, and there 489e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * is no rounding due to the multiplication - the bit pattern is preserved. 490e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 491e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung static const float scale = 1. / (float)(1UL << 15); 492e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 493e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return ival * scale; 494e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 495e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 496e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a packed 24bit Q0.23 value stored little-endian in a uint8_t ptr 497e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to a signed fixed-point 32 bit integer Q0.31 value. The output Q0.31 range 498e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * is [0x80000000, 0x7fffff00] for the fixed-point range [0x800000, 0x7fffff]. 499e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Even though the output range is limited on the positive side, there is no 500e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * DC offset on the output, if the input has no DC offset. 501e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 502e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * Avoid relying on the limited output range, as future implementations may go 503e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to full range. 504e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 505e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline int32_t i32_from_p24(const uint8_t *packed24) 506e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 507e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* convert to 32b */ 508e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#ifdef HAVE_BIG_ENDIAN 509e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return (packed24[2] << 8) | (packed24[1] << 16) | (packed24[0] << 24); 510e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#else 511e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#ifndef HAVE_LITTLE_ENDIAN 512e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung /* check to see if we really have one or the other android endian flags set. */ 513e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#warning "Both HAVE_LITTLE_ENDIAN and HAVE_BIG_ENDIAN not defined, default to little endian" 514e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#endif 515e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung return (packed24[0] << 8) | (packed24[1] << 16) | (packed24[2] << 24); 516e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung#endif 517e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 518e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 5192c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung/* Convert a 32-bit Q0.31 value to single-precision floating-point. 5202c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * The output float range is [-1.0, 1.0] for the fixed-point range 5212c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * [0x80000000, 0x7fffffff]. 5222c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * 5232c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding may occur in the least significant 8 bits for large fixed point 5242c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * values due to storage into the 24-bit floating-point significand. 5252c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung * Rounding will be to nearest, ties to even. 5262c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung */ 5272c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hungstatic inline float float_from_i32(int32_t ival) 5282c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung{ 5292c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung static const float scale = 1. / (float)(1UL << 31); 5302c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 5312c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return ival * scale; 5322c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung} 5332c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung 534e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung/* Convert a packed 24bit Q0.23 value stored native endian in a uint8_t ptr 535e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * to single-precision floating-point. The output float range is [-1.0, 1.0) 536e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * for the fixed-point range [0x800000, 0x7fffff]. 537e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * 538e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung * There is no rounding, the conversion and representation is exact. 539e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung */ 540e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hungstatic inline float float_from_p24(const uint8_t *packed24) 541e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung{ 5422c63fb60f8086000645e82cfb384cc8dfc5d1634Andy Hung return float_from_i32(i32_from_p24(packed24)); 543e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung} 544e0454e2f58e18d954a3de3fa9a9c0e1be3d56f57Andy Hung 545d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung/* Convert a 24-bit Q8.23 value to single-precision floating-point. 546d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * The nominal output float range is [-1.0, 1.0) for the fixed-point 547d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * range [0xff800000, 0x007fffff]. The maximum float range is [-256.0, 256.0). 548d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * 549d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * There is no rounding in the nominal range, the conversion and representation 550d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung * is exact. For values outside the nominal range, rounding is to nearest, ties to even. 551d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung */ 552d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hungstatic inline float float_from_q8_23(int32_t ival) 553d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung{ 554d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung static const float scale = 1. / (float)(1UL << 23); 555d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 556d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung return ival * scale; 557d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung} 558d5829888ea3839910dcf7c94f3308d469c46b7faAndy Hung 559632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 560632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Multiply-accumulate 16-bit terms with 32-bit result: return a + in*v. 561632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 562632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 563632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulAdd(int16_t in, int16_t v, int32_t a) 564632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 565632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 566632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 567632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlabb %[out], %[in], %[v], %[a] \n" 568632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 569632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 570632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 571632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 572632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 573632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + in * (int32_t)v; 574632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 575632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 576632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 577632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 578632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Multiply 16-bit terms with 32-bit result: return in*v. 579632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 580632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 581632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mul(int16_t in, int16_t v) 582632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 583632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 584632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 585632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smulbb %[out], %[in], %[v] \n" 586632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 587632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [in]"%r"(in), [v]"r"(v) 588632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 589632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 590632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 591632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return in * (int32_t)v; 592632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 593632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 594632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 595632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 596632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Similar to mulAdd, but the 16-bit terms are extracted from a 32-bit interleaved stereo pair. 597632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 598632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 599632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a) 600632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 601632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 602632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 603632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 604632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n" 605632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 606632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) 607632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 608632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 609632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n" 610632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 611632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a) 612632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 613632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 614632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 615632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 616632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 617632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + (int16_t)(inRL&0xFFFF) * (int16_t)(vRL&0xFFFF); 618632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 619632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return a + (int16_t)(inRL>>16) * (int16_t)(vRL>>16); 620632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 621632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 622632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 623632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 624632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten/** 625632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten * Similar to mul, but the 16-bit terms are extracted from a 32-bit interleaved stereo pair. 626632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten */ 627632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenstatic inline 628632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kastenint32_t mulRL(int left, uint32_t inRL, uint32_t vRL) 629632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten{ 630632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#if defined(__arm__) && !defined(__thumb__) 631632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten int32_t out; 632632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 633632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smulbb %[out], %[inRL], %[vRL] \n" 634632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 635632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL) 636632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 637632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 638632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten asm( "smultt %[out], %[inRL], %[vRL] \n" 639632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [out]"=r"(out) 640632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : [inRL]"%r"(inRL), [vRL]"r"(vRL) 641632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten : ); 642632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 643632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return out; 644632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#else 645632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten if (left) { 646632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return (int16_t)(inRL&0xFFFF) * (int16_t)(vRL&0xFFFF); 647632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } else { 648632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten return (int16_t)(inRL>>16) * (int16_t)(vRL>>16); 649632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten } 650632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif 651632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten} 652632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 653632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten__END_DECLS 654632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten 655632e0c016c9a518b36f09988b740b3bc1199c3e4Glenn Kasten#endif // ANDROID_AUDIO_PRIMITIVES_H 656