1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_AUDIO_MINIFLOAT_H
18 #define ANDROID_AUDIO_MINIFLOAT_H
19
20 #include <stdint.h>
21 #include <sys/cdefs.h>
22
23 /** \cond */
24 __BEGIN_DECLS
25 /** \endcond */
26
27 /** A single gain expressed as minifloat */
28 typedef uint16_t gain_minifloat_t;
29
30 /** A pair of gain_minifloat_t packed into a single word */
31 typedef uint32_t gain_minifloat_packed_t;
32
33 /** The nominal range of a gain, expressed as a float */
34 #define GAIN_FLOAT_ZERO 0.0f
35 #define GAIN_FLOAT_UNITY 1.0f
36
37 /** Unity gain expressed as a minifloat */
38 #define GAIN_MINIFLOAT_UNITY 0xE000
39
40 /** Pack a pair of gain_mini_float_t into a combined gain_minifloat_packed_t */
gain_minifloat_pack(gain_minifloat_t left,gain_minifloat_t right)41 static inline gain_minifloat_packed_t gain_minifloat_pack(gain_minifloat_t left,
42 gain_minifloat_t right)
43 {
44 return (right << 16) | left;
45 }
46
47 /** Unpack a gain_minifloat_packed_t into the two gain_minifloat_t components */
gain_minifloat_unpack_left(gain_minifloat_packed_t packed)48 static inline gain_minifloat_t gain_minifloat_unpack_left(gain_minifloat_packed_t packed)
49 {
50 return packed & 0xFFFF;
51 }
52
gain_minifloat_unpack_right(gain_minifloat_packed_t packed)53 static inline gain_minifloat_t gain_minifloat_unpack_right(gain_minifloat_packed_t packed)
54 {
55 return packed >> 16;
56 }
57
58 /** A pair of unity gains expressed as a gain_minifloat_packed_t */
59 #define GAIN_MINIFLOAT_PACKED_UNITY gain_minifloat_pack(GAIN_MINIFLOAT_UNITY, GAIN_MINIFLOAT_UNITY)
60
61 /**
62 * Convert a float to the internal representation used for gains.
63 * The nominal range [0.0, 1.0], but the hard range is [0.0, 2.0).
64 * Negative and underflow values are converted to 0.0,
65 * and values larger than the hard maximum are truncated to the hard maximum.
66 *
67 * Minifloats are ordered, and standard comparisons may be used between them
68 * in the gain_minifloat_t representation.
69 *
70 * Details on internal representation of gains, based on mini-floats:
71 * The nominal maximum is 1.0 and the hard maximum is 1 ULP less than 2.0, or +6 dB.
72 * The minimum non-zero value is approximately 1.9e-6 or -114 dB.
73 * Negative numbers, infinity, and NaN are not supported.
74 * There are 13 significand bits specified, 1 implied hidden bit, 3 exponent bits,
75 * and no sign bit. Denormals are supported.
76 */
77 gain_minifloat_t gain_from_float(float f);
78
79 /** Convert the internal representation used for gains to float */
80 float float_from_gain(gain_minifloat_t gain);
81
82 /** \cond */
83 __END_DECLS
84 /** \endcond */
85
86 #endif // ANDROID_AUDIO_MINIFLOAT_H
87