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