16enum class ChannelLayout
27inline constexpr std::string_view channel_layout_names[]{
28 "Auto",
"Numbered",
"Stereo",
"5.1",
"7.1",
"7.1.4",
"Ambisonic"};
32 std::string_view name;
42inline constexpr Speaker stereo[]{{
"L", -30}, {
"R", 30}};
43inline constexpr Speaker s51[]{
44 {
"L", -30}, {
"R", 30}, {
"C", 0}, {
"LFE", 0, 0,
true}, {
"Ls", -110}, {
"Rs", 110}};
45inline constexpr Speaker s71[]{
46 {
"L", -30}, {
"R", 30}, {
"C", 0}, {
"LFE", 0, 0,
true},
47 {
"Lss", -90}, {
"Rss", 90}, {
"Lrs", -150}, {
"Rrs", 150}};
48inline constexpr Speaker s714[]{
49 {
"L", -30}, {
"R", 30}, {
"C", 0}, {
"LFE", 0, 0,
true},
50 {
"Lss", -90}, {
"Rss", 90}, {
"Lrs", -150}, {
"Rrs", 150},
51 {
"Ltf", -45, 45}, {
"Rtf", 45, 45}, {
"Ltr", -135, 45}, {
"Rtr", 135, 45}};
56inline ChannelLayout
resolve(ChannelLayout l,
int channels)
noexcept
58 if(l != ChannelLayout::Auto)
63 return ChannelLayout::Stereo;
65 return ChannelLayout::Surround51;
67 return ChannelLayout::Surround71;
69 return ChannelLayout::Surround714;
71 return ChannelLayout::Numbered;
76inline std::span<const Speaker>
speakers(ChannelLayout l,
int channels)
noexcept
80 case ChannelLayout::Stereo:
81 return detail::stereo;
82 case ChannelLayout::Surround51:
84 case ChannelLayout::Surround71:
86 case ChannelLayout::Surround714:
93inline QString channelLabel(ChannelLayout l,
int channels,
int c)
95 const auto sp =
speakers(l, channels);
96 if(c <
int(sp.size()))
97 return QString::fromLatin1(sp[c].name.data(), sp[c].name.size());
98 if(
resolve(l, channels) == ChannelLayout::Ambisonic)
101 const int n = int(std::sqrt(
double(c)));
102 return QStringLiteral(
"%1.%2").arg(n).arg(c - n * n - n);
104 return QString::number(c + 1);
115 if(
resolve(l, channels) == ChannelLayout::Ambisonic)
116 return c == 0 ? 1. : 0.;
117 const auto sp =
speakers(l, channels);
118 if(c >=
int(sp.size()))
122 const double a = std::abs(sp[c].azimuth);
123 return (a >= 60. && a <= 120. && std::abs(sp[c].elevation) < 30.) ? 1.41 : 1.;
133 std::array<int, 64> channel{};
134 std::array<double, 64> azimuth{};
138inline Ring ring(ChannelLayout l,
int channels)
noexcept
141 const auto sp =
speakers(l, channels);
144 for(
int c = 0; c < int(sp.size()) && c < channels; c++)
146 if(sp[c].lfe || sp[c].elevation > 0)
148 r.channel[r.size] = c;
149 r.azimuth[r.size] = sp[c].azimuth;
153 for(
int i = 1; i < r.size; i++)
154 for(
int j = i; j > 0 && r.azimuth[j - 1] > r.azimuth[j]; j--)
156 std::swap(r.azimuth[j - 1], r.azimuth[j]);
157 std::swap(r.channel[j - 1], r.channel[j]);
161 r.size = std::min(channels, 64);
162 for(
int c = 0; c < r.size; c++)
165 r.azimuth[c] = -180. + 360. * (c + 0.5) / r.size;
Definition BufferDecode.hpp:16
double loudnessWeight(ChannelLayout l, int channels, int c) noexcept
Definition ChannelLayout.hpp:113
ChannelLayout resolve(ChannelLayout l, int channels) noexcept
Definition ChannelLayout.hpp:56
std::span< const Speaker > speakers(ChannelLayout l, int channels) noexcept
The speakers of a layout, empty when it has no fixed positions.
Definition ChannelLayout.hpp:76
Definition ChannelLayout.hpp:132
Definition ChannelLayout.hpp:31
double elevation
Degrees above the listener.
Definition ChannelLayout.hpp:36
double azimuth
Degrees, 0 in front, positive to the right.
Definition ChannelLayout.hpp:34