7#include "../assert.hpp"
9#include "../pickle.hpp"
10#include "../text/ttauri_icon.hpp"
17enum class speaker_mapping : uint64_t {
23 front_left = 0x0'0001,
24 front_right = 0x0'0002,
25 front_center = 0x0'0004,
26 low_frequency = 0x0'0008,
28 back_right = 0x0'0020,
29 front_left_of_center = 0x0'0040,
30 front_right_of_center = 0x0'0080,
31 back_center = 0x0'0100,
33 side_right = 0x0'0400,
35 top_front_left = 0x0'1000,
36 top_front_center = 0x0'2000,
37 top_front_right = 0x0'4000,
38 top_back_left = 0x0'8000,
39 top_back_center = 0x1'0000,
40 top_back_right = 0x2'0000,
44 iso_0 = direct | (0ULL << 32),
45 iso_1 = direct | (1ULL << 32),
46 iso_2 = direct | (2ULL << 32),
47 iso_3 = direct | (3ULL << 32),
48 iso_4 = direct | (4ULL << 32),
49 iso_5 = direct | (5ULL << 32),
50 iso_6 = direct | (6ULL << 32),
51 iso_7 = direct | (7ULL << 32),
52 iso_8 = direct | (8ULL << 32),
55 mono_1_0 = front_center,
56 stereo_2_0 = front_left | front_right,
59 stereo_2_1 = stereo_2_0 | low_frequency,
60 stereo_3_0 = stereo_2_0 | front_center,
61 stereo_3_1 = stereo_3_0 | low_frequency,
62 quad_4_0 = stereo_2_0 | back_left | back_right,
63 quad_side_4_0 = stereo_2_0 | side_left | side_right,
64 hexagonal_6_0 = quad_4_0 | front_center | back_center,
65 hexagonal_6_1 = hexagonal_6_0 | low_frequency,
66 octagonal_8_0 = hexagonal_6_0 | side_left | side_right,
69 surround_3_0 = stereo_2_0 | back_center,
70 surround_4_0 = surround_3_0 | front_center,
71 surround_4_1 = surround_4_0 | low_frequency,
72 surround_5_0 = quad_4_0 | front_center,
73 surround_5_1 = surround_5_0 | low_frequency,
74 surround_7_0 = surround_5_0 | side_left | side_right,
75 surround_7_1 = surround_7_0 | low_frequency,
76 surround_9_0 = surround_7_0 | top_front_left | top_front_right,
77 surround_9_1 = surround_9_0 | low_frequency,
78 surround_11_0 = surround_9_0 | front_left_of_center | front_right_of_center,
79 surround_11_1 = surround_11_0 | low_frequency,
82 surround_side_5_0 = quad_side_4_0 | front_center,
83 surround_side_5_1 = surround_side_5_0 | low_frequency,
84 surround_side_6_0 = surround_side_5_0 | back_center,
85 surround_side_6_1 = surround_side_6_0 | low_frequency,
86 surround_side_7_0 = surround_side_5_0 | front_left_of_center | front_right_of_center,
87 surround_side_7_1 = surround_side_7_0 | low_frequency,
90 surround_wide_6_0 = surround_4_0 | front_left_of_center | front_right_of_center,
91 surround_wide_6_1 = surround_wide_6_0 | low_frequency,
92 surround_wide_7_0 = surround_5_0 | front_left_of_center | front_right_of_center,
93 surround_wide_7_1 = surround_wide_7_0 | low_frequency,
96 surround_atmos_5_1_4 = surround_5_1 | top_front_left | top_front_right | top_back_left | top_back_right,
97 surround_atmos_7_1_4 = surround_7_1 | top_front_left | top_front_right | top_back_left | top_back_right,
100[[nodiscard]]
constexpr bool to_bool(speaker_mapping
const &rhs)
noexcept
102 return static_cast<bool>(
static_cast<uint64_t
>(rhs));
105[[nodiscard]]
constexpr bool holds_invariant(speaker_mapping
const &rhs)
noexcept
107 auto rhs_ =
static_cast<uint64_t
>(rhs);
108 return static_cast<uint32_t
>(rhs_) ? (rhs_ >> 32) == 0 : (rhs_ >> 32) > 0;
111[[nodiscard]]
constexpr bool is_direct(speaker_mapping
const &rhs)
noexcept
113 return static_cast<uint32_t
>(
static_cast<uint64_t
>(rhs)) == 0;
116[[nodiscard]]
constexpr bool is_empty(speaker_mapping
const &rhs)
noexcept
118 return to_underlying(rhs) == 0;
121[[nodiscard]]
constexpr speaker_mapping make_direct_speaker_mapping(
size_t num_speakers)
noexcept
124 ttlet r =
static_cast<speaker_mapping
>(num_speakers << 32);
125 tt_axiom(holds_invariant(r));
129[[nodiscard]]
constexpr speaker_mapping
operator|(speaker_mapping
const &lhs, speaker_mapping
const &rhs)
noexcept
131 tt_axiom((is_empty(lhs) or not is_direct(lhs)) and (is_empty(rhs) or not is_direct(rhs)));
133 ttlet r =
static_cast<speaker_mapping
>(to_underlying(lhs) | to_underlying(rhs));
134 tt_axiom(holds_invariant(r));
138[[nodiscard]]
constexpr speaker_mapping operator&(speaker_mapping
const &lhs, speaker_mapping
const &rhs)
noexcept
140 tt_axiom(not is_direct(lhs) and not is_direct(rhs));
142 ttlet r =
static_cast<speaker_mapping
>(to_underlying(lhs) & to_underlying(rhs));
143 tt_axiom(holds_invariant(r));
147constexpr speaker_mapping &operator|=(speaker_mapping &lhs, speaker_mapping
const &rhs)
noexcept
149 return lhs = lhs | rhs;
152constexpr speaker_mapping &operator&=(speaker_mapping &lhs, speaker_mapping
const &rhs)
noexcept
154 return lhs = lhs & rhs;
157[[nodiscard]]
constexpr size_t num_channels(speaker_mapping
const &rhs)
noexcept
159 if (is_direct(rhs)) {
160 return static_cast<uint64_t
>(rhs) >> 32;
162 return std::popcount(
static_cast<uint64_t
>(rhs));
174 speaker_mapping mapping;
181 speaker_mapping_info{speaker_mapping::stereo_2_0, ttauri_icon::stereo_2_0,
"Stereo 2.0"},
182 speaker_mapping_info{speaker_mapping::stereo_2_1, ttauri_icon::stereo_2_1,
"Stereo 2.1"},
183 speaker_mapping_info{speaker_mapping::stereo_3_0, ttauri_icon::stereo_3_0,
"Stereo 3.0"},
184 speaker_mapping_info{speaker_mapping::stereo_3_1, ttauri_icon::stereo_3_1,
"Stereo 3.1"},
185 speaker_mapping_info{speaker_mapping::quad_4_0, ttauri_icon::quad_4_0,
"Quad 4.0"},
186 speaker_mapping_info{speaker_mapping::quad_side_4_0, ttauri_icon::quad_side_4_0,
"Quad 4.0 (side)"},
187 speaker_mapping_info{speaker_mapping::hexagonal_6_0, ttauri_icon::hexagonal_6_0,
"Hexagonal 6.0"},
188 speaker_mapping_info{speaker_mapping::hexagonal_6_1, ttauri_icon::hexagonal_6_1,
"Hexagonal 6.1"},
189 speaker_mapping_info{speaker_mapping::octagonal_8_0, ttauri_icon::octagonal_8_0,
"Octagonal 8.0"},
190 speaker_mapping_info{speaker_mapping::surround_3_0, ttauri_icon::surround_3_0,
"Surround 3.0"},
191 speaker_mapping_info{speaker_mapping::surround_4_0, ttauri_icon::surround_4_0,
"Surround 4.0"},
192 speaker_mapping_info{speaker_mapping::surround_4_1, ttauri_icon::surround_4_1,
"Surround 4.1"},
193 speaker_mapping_info{speaker_mapping::surround_5_0, ttauri_icon::surround_5_0,
"Surround 5.0"},
194 speaker_mapping_info{speaker_mapping::surround_5_1, ttauri_icon::surround_5_1,
"Surround 5.1"},
195 speaker_mapping_info{speaker_mapping::surround_7_0, ttauri_icon::surround_7_0,
"Surround 7.0"},
196 speaker_mapping_info{speaker_mapping::surround_7_1, ttauri_icon::surround_7_1,
"Surround 7.1"},
197 speaker_mapping_info{speaker_mapping::surround_9_0, ttauri_icon::surround_9_0,
"Surround 9.0"},
198 speaker_mapping_info{speaker_mapping::surround_9_1, ttauri_icon::surround_9_1,
"Surround 9.1"},
199 speaker_mapping_info{speaker_mapping::surround_11_0, ttauri_icon::surround_11_0,
"Surround 11.0"},
200 speaker_mapping_info{speaker_mapping::surround_11_1, ttauri_icon::surround_11_1,
"Surround 11.1"},
201 speaker_mapping_info{speaker_mapping::surround_side_5_0, ttauri_icon::surround_side_5_0,
"Surround 5.0 (side)"},
202 speaker_mapping_info{speaker_mapping::surround_side_5_1, ttauri_icon::surround_side_5_1,
"Surround 5.1 (side)"},
203 speaker_mapping_info{speaker_mapping::surround_side_6_0, ttauri_icon::surround_side_6_0,
"Surround 6.0 (side)"},
204 speaker_mapping_info{speaker_mapping::surround_side_6_1, ttauri_icon::surround_side_6_1,
"Surround 6.1 (side)"},
205 speaker_mapping_info{speaker_mapping::surround_side_7_0, ttauri_icon::surround_side_7_0,
"Surround 7.0 (side)"},
206 speaker_mapping_info{speaker_mapping::surround_side_7_1, ttauri_icon::surround_side_7_1,
"Surround 7.1 (side)"},
207 speaker_mapping_info{speaker_mapping::surround_wide_6_0, ttauri_icon::surround_wide_6_0,
"Surround 6.0 (wide)"},
208 speaker_mapping_info{speaker_mapping::surround_wide_6_1, ttauri_icon::surround_wide_6_1,
"Surround 6.1 (wide)"},
209 speaker_mapping_info{speaker_mapping::surround_wide_7_0, ttauri_icon::surround_wide_7_0,
"Surround 7.0 (wide)"},
210 speaker_mapping_info{speaker_mapping::surround_wide_7_1, ttauri_icon::surround_wide_7_1,
"Surround 7.1 (wide)"},
211 speaker_mapping_info{speaker_mapping::surround_atmos_5_1_4, ttauri_icon::surround_atmos_5_1_4,
"Atmos 5.1.4"},
212 speaker_mapping_info{speaker_mapping::surround_atmos_7_1_4, ttauri_icon::surround_atmos_7_1_4,
"Atmos 7.1.4"},
217 [[nodiscard]]
datum encode(speaker_mapping
const &rhs)
const noexcept
219 return datum{narrow_cast<long long>(to_underlying(rhs))};
222 [[nodiscard]] speaker_mapping
decode(
long long rhs)
const
224 tt_parse_check(rhs >= 0,
"Expect speaker mapping to be encoded as a natural number, got {}.", rhs);
225 return static_cast<speaker_mapping
>(rhs);
228 [[nodiscard]] speaker_mapping
decode(
datum const &rhs)
const
230 if (
auto *i = get_if<long long>(rhs)) {
233 throw parse_error(
"Expect speaker mapping to be encoded as a integer, got {}", rhs);
@ top_center
Align to the top and horizontal-center.
constexpr alignment operator|(vertical_alignment lhs, horizontal_alignment rhs) noexcept
Combine vertical and horizontal alignment.
Definition alignment.hpp:91
Definition speaker_mapping.hpp:173
A dynamic data type.
Definition datum.hpp:213
Exception thrown during parsing on an error.
Definition exception.hpp:26
An image, in different formats.
Definition icon.hpp:19
Encode and decode a type to and from a UTF-8 string.
Definition pickle.hpp:22
T decode(datum rhs) const
Decode a UTF-8 string into a value of a given type.
datum encode(T const &rhs) const noexcept
Encode the value of a type into a UTF-8 string.