JPL Spatial
Sound spatialization and propagation library
Loading...
Searching...
No Matches
GainEncoding.h
Go to the documentation of this file.
1//
2// ██╗██████╗ ██╗ ██╗██████╗ ███████╗
3// ██║██╔══██╗ ██║ ██║██╔══██╗██╔════╝ ** JPLSpatial **
4// ██║██████╔╝ ██║ ██║██████╔╝███████╗
5// ██ ██║██╔═══╝ ██║ ██║██╔══██╗╚════██║ https://github.com/Jaytheway/JPLSpatial
6// ╚█████╔╝██║ ███████╗██║██████╔╝███████║
7// ╚════╝ ╚═╝ ╚══════╝╚═╝╚═════╝ ╚══════╝
8//
9// Copyright 2024 Jaroslav Pevno, JPLSpatial is offered under the terms of the ISC license:
10//
11// Permission to use, copy, modify, and/or distribute this software for any purpose with or
12// without fee is hereby granted, provided that the above copyright notice and this permission
13// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
14// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
16// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#pragma once
21
22#include "JPLSpatial/Core.h"
23
24namespace JPL
25{
26 //==========================================================================
27 // Compact 24-bit packing for normalzied [0, 1] gain values
28 // (little-endian)
29 struct Gain24Bit
30 {
31 static constexpr uint32 cU24max = (1 << 24) - 1;
32 static constexpr float cInv = 1.0f / cU24max;
33
35
36 constexpr Gain24Bit() = default;
37
38 JPL_INLINE explicit constexpr Gain24Bit(float gainNormalized)
39 {
40 constexpr auto cScale = static_cast<float>(1 << 24);
41 uint32 w24 = static_cast<uint32_t>(gainNormalized * cScale);
42 w24 -= (w24 >> 24);
43
44 Bytes[0] = static_cast<uint8>(w24 & 0xFF);
45 Bytes[1] = static_cast<uint8>((w24 >> 8) & 0xFF);
46 Bytes[2] = static_cast<uint8>((w24 >> 16) & 0xFF);
47 }
48
49 JPL_INLINE constexpr Gain24Bit& operator=(float gainNormalized) noexcept
50 {
51 *this = Gain24Bit{ gainNormalized };
52 return *this;
53 }
54
55 JPL_INLINE constexpr operator float() const noexcept
56 {
57 return (static_cast<uint32>(Bytes[0])
58 | (static_cast<uint32>(Bytes[1]) << 8)
59 | (static_cast<uint32>(Bytes[2]) << 16))
60 * cInv;
61 }
62 };
63
64 //==========================================================================
65 // 16-bit packing for normalzied [0, 1] gain values
66 struct Gain16Bit
67 {
68 static constexpr uint32 cU16max = (1 << 16) - 1;
69 static constexpr float cInv = 1.0f / cU16max;
70
72
73 constexpr Gain16Bit() = default;
74
75 JPL_INLINE explicit constexpr Gain16Bit(float gainNormalized)
76 {
77 constexpr auto cScale = static_cast<float>(1 << 16);
78 auto w16 = static_cast<uint32>(gainNormalized * cScale);
79 w16 -= (w16 >> 16);
80 Bytes = w16;
81 }
82
83 JPL_INLINE constexpr Gain16Bit& operator=(float gainNormalized) noexcept
84 {
85 *this = Gain16Bit{ gainNormalized };
86 return *this;
87 }
88
89 JPL_INLINE constexpr operator float() const noexcept
90 {
91 return Bytes * cInv;
92 }
93 };
94
95 //==========================================================================
96 namespace UnitTests
97 {
98 // Constexpr helper: absolute difference
99 constexpr bool approx(float a, float b, float tol) noexcept
100 {
101 return (a > b ? a - b : b - a) <= tol;
102 }
103
104 constexpr float tol16 = Gain16Bit::cInv; // one LSB in amplitude
105 constexpr float tol24 = Gain24Bit::cInv;
106
107 // Mid-range sanity
108 static_assert(approx(static_cast<float>(Gain16Bit{ 0.50f }), 0.50f, tol16), "Gain16 mid-range round-trip failed");
109 static_assert(approx(static_cast<float>(Gain24Bit{ 0.25f }), 0.25f, tol24), "Gain24 mid-range round-trip failed");
110
111 // Edge cases
112 static_assert(static_cast<float>(Gain16Bit{ 0.0f }) == 0.0f, "Gain16 zero failed");
113 static_assert(approx(static_cast<float>(Gain24Bit{ 1.0f }), 1.0f, tol24 * 2), "Gain24 full-scale failed");
114 } // namespace UnitTests
115
116} // namespace JPL
constexpr float tol24
Definition GainEncoding.h:105
constexpr bool approx(float a, float b, float tol) noexcept
Definition GainEncoding.h:99
constexpr float tol16
Definition GainEncoding.h:104
Definition AcousticMaterial.h:36
std::uint32_t uint32
Definition Core.h:311
std::uint16_t uint16
Definition Core.h:310
std::uint8_t uint8
Definition Core.h:309
JPL_INLINE simd min(const simd &a, const simd &b) noexcept
Element-wise min.
Definition SIMD.h:1813
Definition GainEncoding.h:67
JPL_INLINE constexpr Gain16Bit(float gainNormalized)
Definition GainEncoding.h:75
static constexpr uint32 cU16max
Definition GainEncoding.h:68
uint16 Bytes
Definition GainEncoding.h:71
constexpr Gain16Bit()=default
JPL_INLINE constexpr Gain16Bit & operator=(float gainNormalized) noexcept
Definition GainEncoding.h:83
static constexpr float cInv
Definition GainEncoding.h:69
Definition GainEncoding.h:30
constexpr Gain24Bit()=default
static constexpr uint32 cU24max
Definition GainEncoding.h:31
JPL_INLINE constexpr Gain24Bit & operator=(float gainNormalized) noexcept
Definition GainEncoding.h:49
JPL_INLINE constexpr Gain24Bit(float gainNormalized)
Definition GainEncoding.h:38
uint8 Bytes[3]
Definition GainEncoding.h:34
static constexpr float cInv
Definition GainEncoding.h:32