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