1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #if !defined(AudioLayout_h)
10 #include <initializer_list>
11 #include "mozilla/MathAlgorithms.h"
19 // Channel definition is conveniently defined to be in the same order as
20 // WAVEFORMAT && SMPTE, even though this is unused for now.
24 CHANNEL_FRONT_LEFT
= 0,
30 CHANNEL_FRONT_LEFT_OF_CENTER
,
31 CHANNEL_FRONT_RIGHT_OF_CENTER
,
35 // From WAVEFORMAT definition.
37 CHANNEL_TOP_FRONT_LEFT
,
38 CHANNEL_TOP_FRONT_CENTER
,
39 CHANNEL_TOP_FRONT_RIGHT
,
40 CHANNEL_TOP_BACK_LEFT
,
41 CHANNEL_TOP_BACK_CENTER
,
42 CHANNEL_TOP_BACK_RIGHT
48 // The maximum number of channels a channel map can represent.
49 static constexpr uint32_t MAX_CHANNELS
= 32;
51 typedef uint32_t ChannelMap
;
53 ChannelLayout() : mChannelMap(UNKNOWN_MAP
), mValid(false) { }
54 explicit ChannelLayout(uint32_t aChannels
)
55 : ChannelLayout(aChannels
, DefaultLayoutForChannels(aChannels
))
58 ChannelLayout(uint32_t aChannels
, const Channel
* aConfig
)
61 if (aChannels
== 0 || !aConfig
) {
64 mChannels
.AppendElements(aConfig
, aChannels
);
67 explicit ChannelLayout(std::initializer_list
<Channel
> aChannelList
)
68 : ChannelLayout(aChannelList
.size(), aChannelList
.begin())
71 bool operator==(const ChannelLayout
& aOther
) const
73 return mChannels
== aOther
.mChannels
;
75 bool operator!=(const ChannelLayout
& aOther
) const
77 return mChannels
!= aOther
.mChannels
;
79 const Channel
& operator[](uint32_t aIndex
) const
81 MOZ_ASSERT(mChannels
.Length() > aIndex
);
82 return mChannels
[aIndex
];
84 uint32_t Count() const
86 return mChannels
.Length();
88 ChannelMap
Map() const;
90 // Calculate the mapping table from the current layout to aOther such that
91 // one can easily go from one layout to the other by doing:
92 // out[channel] = in[map[channel]].
93 // Returns true if the reordering is possible or false otherwise.
94 // If true, then aMap, if set, will be updated to contain the mapping table
95 // allowing conversion from the current layout to aOther.
96 // If aMap is empty, then MappingTable can be used to simply determine if
97 // the current layout can be easily reordered to aOther.
98 bool MappingTable(const ChannelLayout
& aOther
, nsTArray
<uint8_t>* aMap
= nullptr) const;
99 bool IsValid() const { return mValid
; }
100 bool HasChannel(Channel aChannel
) const
102 return mChannelMap
& (1 << aChannel
);
104 // Return the number of channels found in this ChannelMap.
105 static uint32_t Channels(ChannelMap aMap
)
107 static_assert(sizeof(ChannelMap
) == sizeof(uint32_t),
108 "Must adjust ChannelMap type");
109 return CountPopulation32(aMap
);
112 static ChannelLayout
SMPTEDefault(
113 const ChannelLayout
& aChannelLayout
);
114 static ChannelLayout
SMPTEDefault(ChannelMap aMap
);
116 static constexpr ChannelMap UNKNOWN_MAP
= 0;
118 // Common channel layout definitions.
119 static constexpr ChannelMap LMONO_MAP
= 1 << CHANNEL_FRONT_CENTER
;
120 static constexpr ChannelMap LMONO_LFE_MAP
=
121 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_LFE
;
122 static constexpr ChannelMap LSTEREO_MAP
=
123 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
;
124 static constexpr ChannelMap LSTEREO_LFE_MAP
=
125 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
| 1 << CHANNEL_LFE
;
126 static constexpr ChannelMap L3F_MAP
= 1 << CHANNEL_FRONT_LEFT
|
127 1 << CHANNEL_FRONT_RIGHT
|
128 1 << CHANNEL_FRONT_CENTER
;
129 static constexpr ChannelMap L3F_LFE_MAP
=
130 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
131 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_LFE
;
132 static constexpr ChannelMap L2F1_MAP
= 1 << CHANNEL_FRONT_LEFT
|
133 1 << CHANNEL_FRONT_RIGHT
|
134 1 << CHANNEL_BACK_CENTER
;
135 static constexpr ChannelMap L2F1_LFE_MAP
=
136 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
| 1 << CHANNEL_LFE
|
137 1 << CHANNEL_BACK_CENTER
;
138 static constexpr ChannelMap L3F1_MAP
=
139 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
140 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_BACK_CENTER
;
141 static constexpr ChannelMap LSURROUND_MAP
= L3F1_MAP
;
142 static constexpr ChannelMap L3F1_LFE_MAP
=
143 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
144 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_LFE
| 1 << CHANNEL_BACK_CENTER
;
145 static constexpr ChannelMap L2F2_MAP
=
146 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
147 1 << CHANNEL_SIDE_LEFT
| 1 << CHANNEL_SIDE_RIGHT
;
148 static constexpr ChannelMap L2F2_LFE_MAP
=
149 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
| 1 << CHANNEL_LFE
|
150 1 << CHANNEL_SIDE_LEFT
| 1 << CHANNEL_SIDE_RIGHT
;
151 static constexpr ChannelMap LQUAD_MAP
=
152 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
153 1 << CHANNEL_BACK_LEFT
| 1 << CHANNEL_BACK_RIGHT
;
154 static constexpr ChannelMap LQUAD_LFE_MAP
=
155 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
| 1 << CHANNEL_LFE
|
156 1 << CHANNEL_BACK_LEFT
| 1 << CHANNEL_BACK_RIGHT
;
157 static constexpr ChannelMap L3F2_MAP
=
158 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
159 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_SIDE_LEFT
|
160 1 << CHANNEL_SIDE_RIGHT
;
161 static constexpr ChannelMap L3F2_LFE_MAP
=
162 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
163 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_LFE
| 1 << CHANNEL_SIDE_LEFT
|
164 1 << CHANNEL_SIDE_RIGHT
;
166 static constexpr ChannelMap L5POINT1_SURROUND_MAP
= L3F2_LFE_MAP
;
167 static constexpr ChannelMap L3F2_BACK_MAP
=
168 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
169 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_BACK_LEFT
|
170 1 << CHANNEL_BACK_RIGHT
;
171 static constexpr ChannelMap L3F2_BACK_LFE_MAP
=
172 L3F2_BACK_MAP
| 1 << CHANNEL_LFE
;
173 static constexpr ChannelMap L3F3R_LFE_MAP
=
174 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
175 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_LFE
| 1 << CHANNEL_BACK_CENTER
|
176 1 << CHANNEL_SIDE_LEFT
| 1 << CHANNEL_SIDE_RIGHT
;
177 static ChannelLayout L3F4_LFE
;
178 static constexpr ChannelMap L3F4_LFE_MAP
=
179 1 << CHANNEL_FRONT_LEFT
| 1 << CHANNEL_FRONT_RIGHT
|
180 1 << CHANNEL_FRONT_CENTER
| 1 << CHANNEL_LFE
| 1 << CHANNEL_BACK_LEFT
|
181 1 << CHANNEL_BACK_RIGHT
| 1 << CHANNEL_SIDE_LEFT
|
182 1 << CHANNEL_SIDE_RIGHT
;
184 static ChannelLayout L7POINT1_SURROUND
;
185 static constexpr ChannelMap L7POINT1_SURROUND_MAP
= L3F4_LFE_MAP
;
188 void UpdateChannelMap();
189 const Channel
* DefaultLayoutForChannels(uint32_t aChannels
) const;
190 AutoTArray
<Channel
, MAX_CHANNELS
> mChannels
;
191 ChannelMap mChannelMap
;
204 #if defined(MOZ_SAMPLE_TYPE_FLOAT32)
205 FORMAT_DEFAULT
= FORMAT_FLT
206 #elif defined(MOZ_SAMPLE_TYPE_S16)
207 FORMAT_DEFAULT
= FORMAT_S16
209 #error "Not supported audio type"
213 AudioConfig(const ChannelLayout
& aChannelLayout
,
215 AudioConfig::SampleFormat aFormat
= FORMAT_DEFAULT
,
216 bool aInterleaved
= true);
217 AudioConfig(const ChannelLayout
& aChannelLayout
,
220 AudioConfig::SampleFormat aFormat
= FORMAT_DEFAULT
,
221 bool aInterleaved
= true);
222 // Will create a channel configuration from default SMPTE ordering.
223 AudioConfig(uint32_t aChannels
,
225 AudioConfig::SampleFormat aFormat
= FORMAT_DEFAULT
,
226 bool aInterleaved
= true);
228 const ChannelLayout
& Layout() const { return mChannelLayout
; }
229 uint32_t Channels() const
231 if (!mChannelLayout
.IsValid()) {
234 return mChannelLayout
.Count();
236 uint32_t Rate() const { return mRate
; }
237 SampleFormat
Format() const { return mFormat
; }
238 bool Interleaved() const { return mInterleaved
; }
239 bool operator==(const AudioConfig
& aOther
) const
241 return mChannelLayout
== aOther
.mChannelLayout
&& mRate
== aOther
.mRate
&&
242 mFormat
== aOther
.mFormat
&& mInterleaved
== aOther
.mInterleaved
;
244 bool operator!=(const AudioConfig
& aOther
) const
246 return !(*this == aOther
);
251 return mChannelLayout
.IsValid() && Format() != FORMAT_NONE
&& Rate() > 0;
254 static const char* FormatToString(SampleFormat aFormat
);
255 static uint32_t SampleSize(SampleFormat aFormat
);
256 static uint32_t FormatToBits(SampleFormat aFormat
);
259 // Channels configuration.
260 ChannelLayout mChannelLayout
;
269 SampleFormat mFormat
;
274 } // namespace mozilla
276 #endif // AudioLayout_h