Version
menu

Wwise SDK 2023.1.18
AkSpeakerConfig.h
Go to the documentation of this file.
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Copyright (c) 2025 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #ifndef _AK_SPEAKERCONFIG_H_
28 #define _AK_SPEAKERCONFIG_H_
29 
30 #include AK/SoundEngine/Common/AkTypes.h>
31 #include AK/Tools/Common/AkBitFuncs.h>
32 #include AK/Tools/Common/AkPlatformFuncs.h>
33 
34 /// Standard speakers (channel mask):
35 #define AK_SPEAKER_FRONT_LEFT 0x1 ///
36 #define AK_SPEAKER_FRONT_RIGHT 0x2 ///
37 #define AK_SPEAKER_FRONT_CENTER 0x4 ///
38 #define AK_SPEAKER_LOW_FREQUENCY 0x8 ///
39 #define AK_SPEAKER_BACK_LEFT 0x10 ///
40 #define AK_SPEAKER_BACK_RIGHT 0x20 ///
41 #define AK_SPEAKER_BACK_CENTER 0x100 ///
42 #define AK_SPEAKER_SIDE_LEFT 0x200 ///
43 #define AK_SPEAKER_SIDE_RIGHT 0x400 ///
44 
45 /// "Height" speakers.
46 #define AK_SPEAKER_TOP 0x800 ///
47 #define AK_SPEAKER_HEIGHT_FRONT_LEFT 0x1000 ///
48 #define AK_SPEAKER_HEIGHT_FRONT_CENTER 0x2000 ///
49 #define AK_SPEAKER_HEIGHT_FRONT_RIGHT 0x4000 ///
50 #define AK_SPEAKER_HEIGHT_BACK_LEFT 0x8000 ///
51 #define AK_SPEAKER_HEIGHT_BACK_CENTER 0x10000 ///
52 #define AK_SPEAKER_HEIGHT_BACK_RIGHT 0x20000 ///
53 
54 //
55 // Supported speaker setups. Those are the ones that can be used in the Wwise Sound Engine audio pipeline.
56 //
57 
58 #define AK_SPEAKER_SETUP_MONO AK_SPEAKER_FRONT_CENTER ///
59 #define AK_SPEAKER_SETUP_0POINT1 AK_SPEAKER_LOW_FREQUENCY ///
60 #define AK_SPEAKER_SETUP_1POINT1 (AK_SPEAKER_FRONT_CENTER | AK_SPEAKER_LOW_FREQUENCY) ///
61 #define AK_SPEAKER_SETUP_STEREO (AK_SPEAKER_FRONT_LEFT | AK_SPEAKER_FRONT_RIGHT) ///
62 #define AK_SPEAKER_SETUP_2POINT1 (AK_SPEAKER_SETUP_STEREO | AK_SPEAKER_LOW_FREQUENCY) ///
63 #define AK_SPEAKER_SETUP_3STEREO (AK_SPEAKER_SETUP_STEREO | AK_SPEAKER_FRONT_CENTER) ///
64 #define AK_SPEAKER_SETUP_3POINT1 (AK_SPEAKER_SETUP_3STEREO | AK_SPEAKER_LOW_FREQUENCY) ///
65 #define AK_SPEAKER_SETUP_4 (AK_SPEAKER_SETUP_STEREO | AK_SPEAKER_SIDE_LEFT | AK_SPEAKER_SIDE_RIGHT) ///
66 #define AK_SPEAKER_SETUP_4POINT1 (AK_SPEAKER_SETUP_4 | AK_SPEAKER_LOW_FREQUENCY) ///
67 #define AK_SPEAKER_SETUP_5 (AK_SPEAKER_SETUP_4 | AK_SPEAKER_FRONT_CENTER) ///
68 #define AK_SPEAKER_SETUP_5POINT1 (AK_SPEAKER_SETUP_5 | AK_SPEAKER_LOW_FREQUENCY) ///
69 #define AK_SPEAKER_SETUP_6 (AK_SPEAKER_SETUP_4 | AK_SPEAKER_BACK_LEFT | AK_SPEAKER_BACK_RIGHT) ///
70 #define AK_SPEAKER_SETUP_6POINT1 (AK_SPEAKER_SETUP_6 | AK_SPEAKER_LOW_FREQUENCY) ///
71 #define AK_SPEAKER_SETUP_7 (AK_SPEAKER_SETUP_6 | AK_SPEAKER_FRONT_CENTER) ///
72 #define AK_SPEAKER_SETUP_7POINT1 (AK_SPEAKER_SETUP_7 | AK_SPEAKER_LOW_FREQUENCY) ///
73 #define AK_SPEAKER_SETUP_SURROUND (AK_SPEAKER_SETUP_STEREO | AK_SPEAKER_BACK_CENTER) ///
74 
75 // Note. DPL2 does not really have 4 channels, but it is used by plugins to differentiate from stereo setup.
76 #define AK_SPEAKER_SETUP_DPL2 (AK_SPEAKER_SETUP_4) ///
77 
78 #define AK_SPEAKER_SETUP_HEIGHT_2 (AK_SPEAKER_HEIGHT_FRONT_LEFT | AK_SPEAKER_HEIGHT_FRONT_RIGHT) ///
79 #define AK_SPEAKER_SETUP_HEIGHT_4 (AK_SPEAKER_SETUP_HEIGHT_2 | AK_SPEAKER_HEIGHT_BACK_LEFT | AK_SPEAKER_HEIGHT_BACK_RIGHT) ///
80 #define AK_SPEAKER_SETUP_HEIGHT_5 (AK_SPEAKER_SETUP_HEIGHT_4 | AK_SPEAKER_HEIGHT_FRONT_CENTER) ///
81 #define AK_SPEAKER_SETUP_HEIGHT_ALL (AK_SPEAKER_SETUP_HEIGHT_5 | AK_SPEAKER_HEIGHT_BACK_CENTER) ///
82 #define AK_SPEAKER_SETUP_HEIGHT_4_TOP (AK_SPEAKER_SETUP_HEIGHT_4 | AK_SPEAKER_TOP) ///
83 #define AK_SPEAKER_SETUP_HEIGHT_5_TOP (AK_SPEAKER_SETUP_HEIGHT_5 | AK_SPEAKER_TOP) ///
84 
85 // Auro speaker setups
86 #define AK_SPEAKER_SETUP_AURO_222 (AK_SPEAKER_SETUP_4 | AK_SPEAKER_HEIGHT_FRONT_LEFT | AK_SPEAKER_HEIGHT_FRONT_RIGHT) ///
87 #define AK_SPEAKER_SETUP_AURO_8 (AK_SPEAKER_SETUP_AURO_222 | AK_SPEAKER_HEIGHT_BACK_LEFT | AK_SPEAKER_HEIGHT_BACK_RIGHT) ///
88 #define AK_SPEAKER_SETUP_AURO_9 (AK_SPEAKER_SETUP_AURO_8 | AK_SPEAKER_FRONT_CENTER) ///
89 #define AK_SPEAKER_SETUP_AURO_9POINT1 (AK_SPEAKER_SETUP_AURO_9 | AK_SPEAKER_LOW_FREQUENCY) ///
90 #define AK_SPEAKER_SETUP_AURO_10 (AK_SPEAKER_SETUP_AURO_9 | AK_SPEAKER_TOP) ///
91 #define AK_SPEAKER_SETUP_AURO_10POINT1 (AK_SPEAKER_SETUP_AURO_10 | AK_SPEAKER_LOW_FREQUENCY) ///
92 #define AK_SPEAKER_SETUP_AURO_11 (AK_SPEAKER_SETUP_AURO_10 | AK_SPEAKER_HEIGHT_FRONT_CENTER) ///
93 #define AK_SPEAKER_SETUP_AURO_11POINT1 (AK_SPEAKER_SETUP_AURO_11 | AK_SPEAKER_LOW_FREQUENCY) ///
94 #define AK_SPEAKER_SETUP_AURO_11_740 (AK_SPEAKER_SETUP_7 | AK_SPEAKER_SETUP_HEIGHT_4) ///
95 #define AK_SPEAKER_SETUP_AURO_11POINT1_740 (AK_SPEAKER_SETUP_AURO_11_740 | AK_SPEAKER_LOW_FREQUENCY) ///
96 #define AK_SPEAKER_SETUP_AURO_13_751 (AK_SPEAKER_SETUP_7 | AK_SPEAKER_SETUP_HEIGHT_5 | AK_SPEAKER_TOP) ///
97 #define AK_SPEAKER_SETUP_AURO_13POINT1_751 (AK_SPEAKER_SETUP_AURO_13_751 | AK_SPEAKER_LOW_FREQUENCY) ///
98 
99 // Dolby speaker setups: in Dolby nomenclature, [#plane].[lfe].[#height]
100 #define AK_SPEAKER_SETUP_DOLBY_5_0_2 (AK_SPEAKER_SETUP_5 | AK_SPEAKER_HEIGHT_FRONT_LEFT | AK_SPEAKER_HEIGHT_FRONT_RIGHT ) ///
101 #define AK_SPEAKER_SETUP_DOLBY_5_1_2 (AK_SPEAKER_SETUP_DOLBY_5_0_2 | AK_SPEAKER_LOW_FREQUENCY ) ///
102 #define AK_SPEAKER_SETUP_DOLBY_6_0_2 (AK_SPEAKER_SETUP_6 | AK_SPEAKER_HEIGHT_FRONT_LEFT | AK_SPEAKER_HEIGHT_FRONT_RIGHT ) ///
103 #define AK_SPEAKER_SETUP_DOLBY_6_1_2 (AK_SPEAKER_SETUP_DOLBY_6_0_2 | AK_SPEAKER_LOW_FREQUENCY ) ///
104 #define AK_SPEAKER_SETUP_DOLBY_6_0_4 (AK_SPEAKER_SETUP_DOLBY_6_0_2 | AK_SPEAKER_HEIGHT_BACK_LEFT | AK_SPEAKER_HEIGHT_BACK_RIGHT ) ///
105 #define AK_SPEAKER_SETUP_DOLBY_6_1_4 (AK_SPEAKER_SETUP_DOLBY_6_0_4 | AK_SPEAKER_LOW_FREQUENCY ) ///
106 #define AK_SPEAKER_SETUP_DOLBY_7_0_2 (AK_SPEAKER_SETUP_7 | AK_SPEAKER_HEIGHT_FRONT_LEFT | AK_SPEAKER_HEIGHT_FRONT_RIGHT ) ///
107 #define AK_SPEAKER_SETUP_DOLBY_7_1_2 (AK_SPEAKER_SETUP_DOLBY_7_0_2 | AK_SPEAKER_LOW_FREQUENCY ) ///
108 #define AK_SPEAKER_SETUP_DOLBY_7_0_4 (AK_SPEAKER_SETUP_DOLBY_7_0_2 | AK_SPEAKER_HEIGHT_BACK_LEFT | AK_SPEAKER_HEIGHT_BACK_RIGHT ) ///
109 #define AK_SPEAKER_SETUP_DOLBY_7_1_4 (AK_SPEAKER_SETUP_DOLBY_7_0_4 | AK_SPEAKER_LOW_FREQUENCY ) ///
110 
111 #define AK_SPEAKER_SETUP_ALL_SPEAKERS (AK_SPEAKER_SETUP_7POINT1 | AK_SPEAKER_BACK_CENTER | AK_SPEAKER_SETUP_HEIGHT_ALL | AK_SPEAKER_TOP) ///
112 
113 // Channel indices.
114 // ------------------------------------------------
115 
116 // Channel indices for standard setups on the plane.
117 #define AK_IDX_SETUP_FRONT_LEFT (0) ///
118 #define AK_IDX_SETUP_FRONT_RIGHT (1) ///
119 #define AK_IDX_SETUP_CENTER (2) ///
120 
121 #define AK_IDX_SETUP_NOCENTER_BACK_LEFT (2) ///
122 #define AK_IDX_SETUP_NOCENTER_BACK_RIGHT (3) ///
123 #define AK_IDX_SETUP_NOCENTER_SIDE_LEFT (4) ///
124 #define AK_IDX_SETUP_NOCENTER_SIDE_RIGHT (5) ///
125 
126 #define AK_IDX_SETUP_WITHCENTER_BACK_LEFT (3) ///
127 #define AK_IDX_SETUP_WITHCENTER_BACK_RIGHT (4) ///
128 #define AK_IDX_SETUP_WITHCENTER_SIDE_LEFT (5) ///
129 #define AK_IDX_SETUP_WITHCENTER_SIDE_RIGHT (6) ///
130 
131 #define AK_IDX_SETUP_WITHCENTER_HEIGHT_FRONT_LEFT (7) ///
132 #define AK_IDX_SETUP_WITHCENTER_HEIGHT_FRONT_RIGHT (8) ///
133 #define AK_IDX_SETUP_WITHCENTER_HEIGHT_BACK_LEFT (9) ///
134 #define AK_IDX_SETUP_WITHCENTER_HEIGHT_BACK_RIGHT (10) ///
135 
136 // Channel indices for specific setups.
137 #define AK_IDX_SETUP_0_LFE (0) ///
138 
139 #define AK_IDX_SETUP_1_CENTER (0) ///
140 #define AK_IDX_SETUP_1_LFE (1) ///
141 
142 #define AK_IDX_SETUP_2_LEFT (0) ///
143 #define AK_IDX_SETUP_2_RIGHT (1) ///
144 #define AK_IDX_SETUP_2_LFE (2) ///
145 
146 #define AK_IDX_SETUP_3_LEFT (0) ///
147 #define AK_IDX_SETUP_3_RIGHT (1) ///
148 #define AK_IDX_SETUP_3_CENTER (2) ///
149 #define AK_IDX_SETUP_3_LFE (3) ///
150 
151 #define AK_IDX_SETUP_4_FRONTLEFT (0) ///
152 #define AK_IDX_SETUP_4_FRONTRIGHT (1) ///
153 #define AK_IDX_SETUP_4_REARLEFT (2) ///
154 #define AK_IDX_SETUP_4_REARRIGHT (3) ///
155 #define AK_IDX_SETUP_4_LFE (4) ///
156 
157 #define AK_IDX_SETUP_5_FRONTLEFT (0) ///
158 #define AK_IDX_SETUP_5_FRONTRIGHT (1) ///
159 #define AK_IDX_SETUP_5_CENTER (2) ///
160 #define AK_IDX_SETUP_5_REARLEFT (3) ///
161 #define AK_IDX_SETUP_5_REARRIGHT (4) ///
162 #define AK_IDX_SETUP_5_LFE (5) ///
163 
164 #define AK_IDX_SETUP_6_FRONTLEFT (0) ///
165 #define AK_IDX_SETUP_6_FRONTRIGHT (1) ///
166 #define AK_IDX_SETUP_6_REARLEFT (2) ///
167 #define AK_IDX_SETUP_6_REARRIGHT (3) ///
168 #define AK_IDX_SETUP_6_SIDELEFT (4) ///
169 #define AK_IDX_SETUP_6_SIDERIGHT (5) ///
170 #define AK_IDX_SETUP_6_LFE (6) ///
171 
172 #define AK_IDX_SETUP_7_FRONTLEFT (0) ///
173 #define AK_IDX_SETUP_7_FRONTRIGHT (1) ///
174 #define AK_IDX_SETUP_7_CENTER (2) ///
175 #define AK_IDX_SETUP_7_REARLEFT (3) ///
176 #define AK_IDX_SETUP_7_REARRIGHT (4) ///
177 #define AK_IDX_SETUP_7_SIDELEFT (5) ///
178 #define AK_IDX_SETUP_7_SIDERIGHT (6) ///
179 #define AK_IDX_SETUP_7_LFE (7) ///
180 
181 //
182 // Extra speaker setups. This is a more exhaustive list of speaker setups, which might not all be supported
183 // by the Wwise Sound Engine audio pipeline.
184 //
185 
186 #define AK_SPEAKER_SETUP_0_1 ( AK_SPEAKER_LOW_FREQUENCY ) //0.1
187 
188 #define AK_SPEAKER_SETUP_1_0_CENTER ( AK_SPEAKER_FRONT_CENTER ) //1.0 (C)
189 #define AK_SPEAKER_SETUP_1_1_CENTER ( AK_SPEAKER_FRONT_CENTER | AK_SPEAKER_LOW_FREQUENCY ) //1.1 (C)
190 
191 #define AK_SPEAKER_SETUP_2_0 ( AK_SPEAKER_FRONT_LEFT | AK_SPEAKER_FRONT_RIGHT ) //2.0
192 #define AK_SPEAKER_SETUP_2_1 ( AK_SPEAKER_FRONT_LEFT | AK_SPEAKER_FRONT_RIGHT | AK_SPEAKER_LOW_FREQUENCY ) //2.1
193 
194 #define AK_SPEAKER_SETUP_3_0 ( AK_SPEAKER_FRONT_LEFT | AK_SPEAKER_FRONT_RIGHT | AK_SPEAKER_FRONT_CENTER ) //3.0
195 #define AK_SPEAKER_SETUP_3_1 ( AK_SPEAKER_SETUP_3_0 | AK_SPEAKER_LOW_FREQUENCY ) //3.1
196 
197 #define AK_SPEAKER_SETUP_FRONT ( AK_SPEAKER_SETUP_3_0 )
198 
199 #define AK_SPEAKER_SETUP_4_0 ( AK_SPEAKER_SETUP_4 )
200 #define AK_SPEAKER_SETUP_4_1 ( AK_SPEAKER_SETUP_4POINT1 )
201 #define AK_SPEAKER_SETUP_5_0 ( AK_SPEAKER_SETUP_5 )
202 #define AK_SPEAKER_SETUP_5_1 ( AK_SPEAKER_SETUP_5POINT1 )
203 
204 #define AK_SPEAKER_SETUP_6_0 ( AK_SPEAKER_SETUP_6 )
205 #define AK_SPEAKER_SETUP_6_1 ( AK_SPEAKER_SETUP_6POINT1 )
206 #define AK_SPEAKER_SETUP_7_0 ( AK_SPEAKER_SETUP_7 )
207 #define AK_SPEAKER_SETUP_7_1 ( AK_SPEAKER_SETUP_7POINT1 )
208 
209 // Standard/largest setup definitions.
210 #define AK_SPEAKER_SETUP_DEFAULT_PLANE (AK_SPEAKER_SETUP_7POINT1) ///
211 #define AK_SUPPORTED_STANDARD_CHANNEL_MASK (AK_SPEAKER_SETUP_ALL_SPEAKERS) ///
212 #define AK_STANDARD_MAX_NUM_CHANNELS (8) ///
213 
214 #define AK_MAX_AMBISONICS_ORDER (5)
215 
216 // Helpers.
217 inline void AK_SPEAKER_SETUP_FIX_LEFT_TO_CENTER( AkUInt32 &io_uChannelMask )
218 {
219  if( !(io_uChannelMask & AK_SPEAKER_FRONT_CENTER)
220  && !(io_uChannelMask & AK_SPEAKER_FRONT_RIGHT)
221  && (io_uChannelMask & AK_SPEAKER_FRONT_LEFT) )
222  {
223  io_uChannelMask &= ~AK_SPEAKER_FRONT_LEFT; // remove left
224  io_uChannelMask |= AK_SPEAKER_FRONT_CENTER; // add center
225  }
226 }
227 
228 inline void AK_SPEAKER_SETUP_FIX_REAR_TO_SIDE( AkUInt32 &io_uChannelMask )
229 {
230  if( io_uChannelMask & ( AK_SPEAKER_BACK_LEFT ) && !( io_uChannelMask & AK_SPEAKER_SIDE_LEFT ) )
231  {
232  io_uChannelMask &= ~( AK_SPEAKER_BACK_LEFT | AK_SPEAKER_BACK_RIGHT ); // remove rears
233  io_uChannelMask |= ( AK_SPEAKER_SIDE_LEFT | AK_SPEAKER_SIDE_RIGHT ); // add sides
234  }
235 }
236 
237 inline void AK_SPEAKER_SETUP_CONVERT_TO_SUPPORTED( AkUInt32 &io_uChannelMask )
238 {
239  AK_SPEAKER_SETUP_FIX_LEFT_TO_CENTER( io_uChannelMask );
240  AK_SPEAKER_SETUP_FIX_REAR_TO_SIDE( io_uChannelMask );
241 }
242 
243 /// Ambisonics configurations (corresponding to AkChannelConfig::eConfigType == AK_ChannelConfigType_Ambisonic).
244 /// Convention: X points towards the front, and XYZ follow a right-hand rule, so Y is the side vector (pointing to the left).
245 /// Channel presence and ordering are predefined according to the number of channels. The ordering convention is ACN,
246 /// with the mapping of components to number of channels detailed below (source: https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats).
247 /// Normalization natively used in Wwise is SN3D.
248 ///
249 ///
250 ///
251 ///
252 ///
253 ///
254 ///
255 ///
256 ///
Number of channels OrderDescriptionLayout of components
HorizontalVertical
1     0    0       mono 
4     1    1       first-order full sphere  WYZX
9     2    2       second-order full sphere  WYZXVTRSU
16     3    3       third-order full sphere  WYZXVTRSUQOMKLNP
257 
258 namespace AK
259 {
260 
261 /// Returns the number of channels of a given channel configuration.
262 static inline AkUInt8 ChannelMaskToNumChannels( AkChannelMask in_uChannelMask )
263 {
264  return (AkUInt8)AKPLATFORM::AkPopCount(in_uChannelMask);
265 }
266 
267 /// Returns a 'best guess' channel configuration from a given number of channels.
268 /// Will return 0 if no guess can be made.
269 static inline AkChannelMask ChannelMaskFromNumChannels( unsigned int in_uNumChannels )
270 {
271  AkChannelMask uChannelMask = 0;
272 
273  switch ( in_uNumChannels )
274  {
275  case 1:
276  uChannelMask = AK_SPEAKER_SETUP_1_0_CENTER;
277  break;
278  case 2:
279  uChannelMask = AK_SPEAKER_SETUP_2_0;
280  break;
281  case 3:
282  uChannelMask = AK_SPEAKER_SETUP_2_1;
283  break;
284  case 4:
285  uChannelMask = AK_SPEAKER_SETUP_4_0;
286  break;
287  case 5:
288  uChannelMask = AK_SPEAKER_SETUP_5_0;
289  break;
290  case 6:
291  uChannelMask = AK_SPEAKER_SETUP_5_1;
292  break;
293  case 7:
294  uChannelMask = AK_SPEAKER_SETUP_7;
295  break;
296  case 8:
297  uChannelMask = AK_SPEAKER_SETUP_7POINT1;
298  break;
299  }
300 
301  return uChannelMask;
302 }
303 
304 /// Converts a channel bit to a channel index (in Wwise pipeline ordering - LFE at the end), given a channel mask in_uChannelMask.
305 /// \return Channel index.
306 static inline AkUInt8 ChannelBitToIndex(AkChannelMask in_uChannelBit, AkChannelMask in_uChannelMask)
307 {
308 #ifdef AKASSERT
309  AKASSERT(ChannelMaskToNumChannels(in_uChannelBit) == 1);
310 #endif
311  if (in_uChannelBit == AK_SPEAKER_LOW_FREQUENCY)
312  return ChannelMaskToNumChannels(in_uChannelMask) - 1;
313  return ChannelMaskToNumChannels(in_uChannelMask & ~AK_SPEAKER_LOW_FREQUENCY & (in_uChannelBit - 1)); // Count all channels prior this one except the LFE
314 }
315 
316 /// Returns true when the LFE channel is present in a given channel configuration.
317 /// \return True if the LFE channel is present.
318 AkForceInline bool HasLFE(AkChannelMask in_uChannelMask)
319 {
320  return (in_uChannelMask & AK_SPEAKER_LOW_FREQUENCY) > 0;
321 }
322 
323 /// Returns true when the center channel is present in a given channel configuration.
324 /// Note that mono configurations have one channel which is arbitrary set to AK_SPEAKER_FRONT_CENTER,
325 /// so HasCenter() returns true for mono signals.
326 /// \return True if the center channel is present.
327 AkForceInline bool HasCenter(AkChannelMask in_uChannelMask)
328 {
329  // All supported non-mono configurations have an AK_SPEAKER_FRONT_LEFT.
330  return (in_uChannelMask & AK_SPEAKER_FRONT_CENTER) > 0;
331 }
332 
333 /// Returns the number of angle values required to represent the given channel configuration.
334 /// Use this function with supported 2D standard channel configurations only.
335 /// \sa AK::SoundEngine::SetSpeakerAngles().
337 {
338 #ifdef AKASSERT
339  AKASSERT((in_uChannelMask & ~AK_SPEAKER_SETUP_DEFAULT_PLANE) == 0);
340 #endif
341 
342  // LFE is irrelevant.
343  in_uChannelMask &= ~AK_SPEAKER_LOW_FREQUENCY;
344  // Center speaker is always in the center and thus does not require an angle.
345  in_uChannelMask &= ~AK_SPEAKER_FRONT_CENTER;
346  // We should have complete pairs at this point, unless there is a speaker at 180 degrees,
347  // in which case we need one more angle to specify it.
348 #ifdef AKASSERT
349  AKASSERT((in_uChannelMask & AK_SPEAKER_BACK_CENTER) || ((ChannelMaskToNumChannels(in_uChannelMask) % 2) == 0));
350 #endif
351  return ChannelMaskToNumChannels(in_uChannelMask) >> 1;
352 }
353 
354 /// Channel ordering type.
356 {
357  ChannelOrdering_Standard, // L-R-C-LFE-RL-RR-RC-SL-SR-HL-HR-HC-HRL-HRR-HRC-T
358  ChannelOrdering_RunTime // L-R-C-RL-RR-RC-SL-SR-HL-HR-HC-HRL-HRR-HRC-T-LFE
359 };
360 
361 /// Returns true if standard configuration represented by channel mask has surround
362 /// channels, either defined as side or back channels.
364 {
365  return ( in_uChannelMask & AK_SPEAKER_BACK_LEFT || in_uChannelMask & AK_SPEAKER_SIDE_LEFT );
366 }
367 
368 /// Returns true if standard configuration represented by channel mask has strictly one
369 /// pair of surround channels, either defined as side or back channels. 7.1 has two pairs
370 /// of surround channels and would thus return false.
372 {
373  return ( ( ( in_uChannelMask & AK_SPEAKER_BACK_LEFT ) != 0 ) ^ ( ( in_uChannelMask & AK_SPEAKER_SIDE_LEFT ) != 0 ) );
374 }
375 
376 /// Returns true if standard configuration represented by channel mask has two
377 /// pair of surround channels, that is, side and back channels. 7.1 has two pairs
378 /// of surround channels and would thus return true, whereas 5.1 would return false.
380 {
381  return ( in_uChannelMask & AK_SPEAKER_BACK_LEFT && in_uChannelMask & AK_SPEAKER_SIDE_LEFT );
382 }
383 
384 /// Returns true if standard configuration represented by channel mask has at least one "height" channel (above the plane).
386 {
387  return (in_uChannelMask & ~AK_SPEAKER_SETUP_DEFAULT_PLANE) > 0;
388 }
389 
390 /// Takes a channel mask and swap back channels with side channels if there is just
391 /// one pair of surround channels.
393 {
394  if ( HasStrictlyOnePairOfSurroundChannels( in_uChannelMask ) )
395  {
396  in_uChannelMask &= ~( AK_SPEAKER_BACK_LEFT | AK_SPEAKER_BACK_RIGHT ); // remove rears
397  in_uChannelMask |= ( AK_SPEAKER_SIDE_LEFT | AK_SPEAKER_SIDE_RIGHT ); // add sides
398  }
399  return in_uChannelMask;
400 }
401 
402 /// Convert channel indices as they are ordered in standard (WAV) or Wwise sound engine (WEM) wave files
403 /// (which follow channel mask bit values, except that the LFE is at the end in the case of WEMs)
404 /// into display indices. Desired display order is L-R-C-SL-SR-RL-RR-HL-HR-HC-HRL-HRR-HRC-T-LFE. Note that 4-5.x configurations
405 /// may define back or side channels. Either way they are "Surround" channels and are assigned to "SL, SR" names.
406 static inline unsigned int StdChannelIndexToDisplayIndex( AkChannelOrdering in_eOrdering, unsigned int in_uChannelMask, unsigned int in_uChannelIdx )
407 {
408  if ( in_eOrdering == ChannelOrdering_Standard )
409  {
410  unsigned int uNumChannelsFront = ChannelMaskToNumChannels( in_uChannelMask & AK_SPEAKER_SETUP_FRONT );
411  if ( ( in_uChannelMask & AK_SPEAKER_LOW_FREQUENCY )
412  && ( in_uChannelIdx == uNumChannelsFront ) )
413  {
414  // Lfe. Return penultimate channel.
415  in_uChannelIdx = ChannelMaskToNumChannels( in_uChannelMask ) - 1;
416  }
417  else if ( in_uChannelIdx >= uNumChannelsFront ) // strictly greater than uNumChannelsFront (lfe index) if lfe is present, greater or equal otherwise.
418  {
419  // Back channel. Return index or index-1 if there is an LFE (uLfeOffset==1).
420  unsigned int uLfeOffset = ( in_uChannelMask & AK_SPEAKER_LOW_FREQUENCY ) ? 1 : 0;
421 
422  // 6-7.x: Need to swap back and sides.
423  if ( HasSideAndRearChannels( in_uChannelMask ) )
424  {
425  unsigned int uRearIdx = uNumChannelsFront + uLfeOffset;
426  unsigned int uSideIdx = uRearIdx + 2;
427  unsigned int uAfterSideIdx = uSideIdx + 2;
428  if ( in_uChannelIdx
429  {
430  if ( in_uChannelIdx >= uSideIdx )
431  in_uChannelIdx -= 2; // input is side, swap it with back.
432  else
433  in_uChannelIdx += 2; // input is back, swap it with side.
434  }
435  }
436  in_uChannelIdx -= uLfeOffset; // compensate for LFE if it was skipped above.
437  }
438  }
439  else
440  {
441  // 6-7.x: Need to swap back and sides.
442  if ( HasSideAndRearChannels( in_uChannelMask ) )
443  {
444  unsigned int uRearIdx = ChannelMaskToNumChannels( in_uChannelMask & AK_SPEAKER_SETUP_FRONT );
445  unsigned int uMaxIdx = uRearIdx + 4; // Side and rear channels.
446 
447  if ( in_uChannelIdx >= uRearIdx
448  && in_uChannelIdx
449  {
450  // Surround channel (not LFE).
451  unsigned int uSideIdx = uRearIdx + 2;
452  if ( in_uChannelIdx >= uSideIdx )
453  in_uChannelIdx -= 2; // input is side, swap it with back.
454  else
455  in_uChannelIdx += 2; // input is back, swap it with side.
456  }
457  }
458  }
459 
460  return in_uChannelIdx;
461 }
462 
463 } // namespace AK
464 
465 /// Channel configuration type.
467 {
472 
475 };
476 
477 /// Defines a channel configuration.
478 /// Examples:
479 /// \code
480 /// AkChannelConfig cfg;
481 ///
482 /// // Create a stereo configuration.
483 /// cfg.SetStandard(AK_SPEAKER_SETUP_STEREO);
484 ///
485 /// // Create a 7.1.4 configuration (7.1 plus 4 height channels).
486 /// cfg.SetStandard(AK_SPEAKER_SETUP_AURO_11POINT1_740);
487 /// // or
488 /// cfg.SetStandard(AK_SPEAKER_SETUP_DOLBY_7_1_4);
489 ///
490 /// // Create a 3rd order ambisonic configuration.
491 /// cfg.SetAmbisonic(16); // pass in the number of spherical harmonics, (N+1)^2, where N is the ambisonics order.
492 ///
493 /// // Invalidate (usually means "As Parent")
494 /// cfg.Clear();
495 /// \endcode
497 {
498  // Channel config:
499  // - uChannelMask is a bit field, whose channel identifiers depend on AkChannelConfigType (up to 20). Channel bits are defined in AkSpeakerConfig.h.
500  // - eConfigType is a code that completes the identification of channels by uChannelMask.
501  // - uNumChannels is the number of channels, identified (deduced from channel mask) or anonymous (set directly).
505 
506  /// Construct standard channel config from channel mask
508  {
509  return AkChannelConfig(AK::ChannelMaskToNumChannels(in_uChannelMask), in_uChannelMask);
510  }
511 
512  // Construct anonymous channel config from number of channels
514  {
515  return AkChannelConfig(in_uNumChannels, 0);
516  }
517 
518  /// Construct ambisonic channel config from number of channels (NOT order)
520  {
521  AkChannelConfig cfg;
522  cfg.SetAmbisonic(in_uNumChannels);
523  return cfg;
524  }
525 
526  // Construct object-based channel config
528  {
529  AkChannelConfig cfg;
530  cfg.SetObject();
531  return cfg;
532  }
533 
534  /// Constructor. Clears / sets the channel config in "invalid" state (IsValid() returns false).
536  : uNumChannels(0)
537  , eConfigType(0)
538  , uChannelMask(0)
539  {
540  }
541 
542  /// Constructor. Sets number of channels, and config type according to whether channel mask is defined or not. If defined, it must be consistent with the number of channels.
543  AkForceInline AkChannelConfig(AkUInt32 in_uNumChannels, AkUInt32 in_uChannelMask)
544  {
545  // Input arguments should be consistent.
546  SetStandardOrAnonymous(in_uNumChannels, in_uChannelMask);
547  }
548 
549  /// Operator != with a 32-bit word.
550  AkForceInline bool operator!=(AkUInt32 in_uBitField)
551  {
552  return (*((AkUInt32*)this) != in_uBitField);
553  }
554 
555  /// Clear the channel config. Becomes "invalid" (IsValid() returns false).
557  {
558  uNumChannels = 0;
559  eConfigType = 0;
560  uChannelMask = 0;
561  }
562 
563  /// Set channel config as a standard configuration specified with given channel mask.
564  AkForceInline void SetStandard(AkUInt32 in_uChannelMask)
565  {
566  uNumChannels = AK::ChannelMaskToNumChannels(in_uChannelMask);
568  uChannelMask = in_uChannelMask;
569  }
570 
571  /// Set channel config as either a standard or an anonymous configuration, specified with both a given channel mask (0 if anonymous) and a number of channels (which must match the channel mask if standard).
572  AkForceInline void SetStandardOrAnonymous(AkUInt32 in_uNumChannels, AkUInt32 in_uChannelMask)
573  {
574 #ifdef AKASSERT
575  AKASSERT(in_uChannelMask == 0 || in_uNumChannels == AK::ChannelMaskToNumChannels(in_uChannelMask));
576 #endif
577  uNumChannels = in_uNumChannels;
579  uChannelMask = in_uChannelMask;
580  }
581 
582  /// Set channel config as an anonymous configuration specified with given number of channels.
583  AkForceInline void SetAnonymous(AkUInt32 in_uNumChannels)
584  {
585  uNumChannels = in_uNumChannels;
587  uChannelMask = 0;
588  }
589 
590  /// Set channel config as an ambisonic configuration specified with given number of channels.
591  AkForceInline void SetAmbisonic(AkUInt32 in_uNumChannels)
592  {
593  uNumChannels = in_uNumChannels;
595  uChannelMask = 0;
596  }
597 
598  /// Set channel config as an object-based configuration (implies dynamic number of objects).
600  {
601  uNumChannels = 0;
603  uChannelMask = 0;
604  }
605 
606  /// Set channel config as the main mix channel configuration
608  {
609  uNumChannels = 0;
611  uChannelMask = 0;
612  }
613 
614  /// Set channel config as the passthrough mix channel configuration
616  {
617  uNumChannels = 0;
619  uChannelMask = 0;
620  }
621 
622  /// Returns true if valid, false otherwise (as when it is constructed, or invalidated using Clear()).
623  AkForceInline bool IsValid() const
624  {
625  return eConfigType AK_ChannelConfigType_Objects && (uNumChannels != 0 || eConfigType == AK_ChannelConfigType_Objects);
626  }
627 
628  /// Serialize channel config into a 32-bit word.
630  {
631  return uNumChannels | (eConfigType uChannelMask
632  }
633 
634  /// Deserialize channel config from a 32-bit word.
635  AkForceInline void Deserialize(AkUInt32 in_uChannelConfig)
636  {
637  uNumChannels = in_uChannelConfig & 0x000000ff;
638  eConfigType = (in_uChannelConfig >> 8) & 0x0000000f;
639  uChannelMask = (in_uChannelConfig >> 12) & 0x000fffff;
640  }
641 
642  /// Returns a new config based on 'this' with no LFE.
644  {
645  AkChannelConfig newConfig = *this;
646  AkUInt32 uNewChannelMask = newConfig.uChannelMask & ~AK_SPEAKER_LOW_FREQUENCY;
647  AkUInt32 uNumLFEChannel = (newConfig.uChannelMask - uNewChannelMask) >> 3; // 0 or 1
648 #ifdef AKASSERT
649  AKASSERT(uNumLFEChannel == 0 || uNumLFEChannel == 1);
650 #endif
651  newConfig.uNumChannels -= uNumLFEChannel;
652  newConfig.uChannelMask = uNewChannelMask;
653  return newConfig;
654  }
655 
656  /// Returns a new config based on 'this' with no Front Center channel.
658  {
659  AkChannelConfig newConfig = *this;
660  AkUInt32 uNewChannelMask = newConfig.uChannelMask & ~AK_SPEAKER_FRONT_CENTER;
661  AkUInt32 uNumCenterChannel = (newConfig.uChannelMask - uNewChannelMask) >> 2; // 0 or 1.
662 #ifdef AKASSERT
663  AKASSERT(uNumCenterChannel == 0 || uNumCenterChannel == 1);
664 #endif
665  newConfig.uNumChannels -= uNumCenterChannel;
666  newConfig.uChannelMask = uNewChannelMask;
667  return newConfig;
668  }
669 
670  /// Operator ==
671  AkForceInline bool operator==(const AkChannelConfig & in_other) const
672  {
673  return uNumChannels == in_other.uNumChannels
674  && eConfigType == in_other.eConfigType
675  && uChannelMask == in_other.uChannelMask;
676  }
677 
678  /// Operator !=
679  AkForceInline bool operator!=(const AkChannelConfig & in_other) const
680  {
681  return uNumChannels != in_other.uNumChannels
682  || eConfigType != in_other.eConfigType
683  || uChannelMask != in_other.uChannelMask;
684  }
685 
686  /// Query if LFE channel is present.
687  /// \return True when LFE channel is present
688  AkForceInline bool HasLFE() const
689  {
690  return AK::HasLFE(uChannelMask);
691  }
692 
693  /// Query if center channel is present.
694  /// Note that mono configurations have one channel which is arbitrary set to AK_SPEAKER_FRONT_CENTER,
695  /// so HasCenter() returns true for mono signals.
696  /// \return True when center channel is present and configuration has more than 2 channels.
698  {
699  return AK::HasCenter(uChannelMask);
700  }
701 };
702 
703 #endif //_AK_SPEAKERCONFIG_H_
AkForceInline bool operator!=(AkUInt32 in_uBitField)
Operator != with a 32-bit word.
AkForceInline bool HasLFE(AkChannelMask in_uChannelMask)
AkForceInline void SetStandardOrAnonymous(AkUInt32 in_uNumChannels, AkUInt32 in_uChannelMask)
Set channel config as either a standard or an anonymous configuration, specified with both a given ch...
static AkForceInline AkChannelConfig Ambisonic(AkUInt32 in_uNumChannels)
Construct ambisonic channel config from number of channels (NOT order)
#define AK_SPEAKER_SETUP_5_0
Audiokinetic namespace.
AkForceInline bool HasCenter() const
AkForceInline AkChannelMask BackToSideChannels(AkChannelMask in_uChannelMask)
AkUInt32 uNumChannels
Number of channels.
void AK_SPEAKER_SETUP_FIX_REAR_TO_SIDE(AkUInt32 &io_uChannelMask)
#define AK_SPEAKER_SETUP_1_0_CENTER
AkUInt32 uChannelMask
Channel mask (configuration).
@ ChannelOrdering_Standard
@ AK_ChannelConfigType_Standard
Channels must be identified with standard defines in AkSpeakerConfigs.
AkForceInline bool HasCenter(AkChannelMask in_uChannelMask)
#define AK_SPEAKER_SETUP_7POINT1
7.1 setup channel mask
#define AK_SPEAKER_BACK_LEFT
Rear left speaker bit mask.
AkUInt32 AkChannelMask
Channel mask (similar to WAVE_FORMAT_EXTENSIBLE). Bit values are defined in AkSpeakerConfig....
Definition: AkTypes.h:81
uint8_t AkUInt8
Unsigned 8-bit integer.
AkForceInline AkChannelConfig()
Constructor. Clears / sets the channel config in "invalid" state (IsValid() returns false).
AkForceInline void SetAmbisonic(AkUInt32 in_uNumChannels)
Set channel config as an ambisonic configuration specified with given number of channels.
AkForceInline AkUInt32 AkPopCount(AkUInt32 in_bits)
Definition: AkBitFuncs.h:68
@ AK_ChannelConfigType_Objects
Object-based configurations.
#define AK_SPEAKER_FRONT_RIGHT
Front right speaker bit mask.
AkForceInline AkUInt32 Serialize() const
Serialize channel config into a 32-bit word.
@ AK_ChannelConfigType_Ambisonic
Ambisonics. Channel mask == 0 and channels follow standard ambisonic order.
static unsigned int StdChannelIndexToDisplayIndex(AkChannelOrdering in_eOrdering, unsigned int in_uChannelMask, unsigned int in_uChannelIdx)
AkForceInline void SetSameAsPassthrough()
Set channel config as the passthrough mix channel configuration.
AkForceInline void SetAnonymous(AkUInt32 in_uNumChannels)
Set channel config as an anonymous configuration specified with given number of channels.
AkForceInline AkChannelConfig RemoveCenter() const
Returns a new config based on 'this' with no Front Center channel.
static AkUInt8 ChannelBitToIndex(AkChannelMask in_uChannelBit, AkChannelMask in_uChannelMask)
#define AK_SPEAKER_SETUP_DEFAULT_PLANE
All speakers on the plane, supported on this platform.
AkForceInline bool operator!=(const AkChannelConfig &in_other) const
Operator !=.
@ AK_ChannelConfigType_UseDevicePassthrough
Special setting for bus objects to use the audio device passthrough configuration.
AkForceInline AkUInt32 GetNumberOfAnglesForConfig(AkChannelMask in_uChannelMask)
static AkForceInline AkChannelConfig Anonymous(AkUInt32 in_uNumChannels)
#define AK_SPEAKER_SIDE_LEFT
Side left speaker bit mask.
#define AKASSERT(Condition)
Definition: AkAssert.h:67
#define AK_SPEAKER_BACK_CENTER
Rear center speaker ("surround speaker") bit mask.
static AkChannelMask ChannelMaskFromNumChannels(unsigned int in_uNumChannels)
AkForceInline void Clear()
Clear the channel config. Becomes "invalid" (IsValid() returns false).
AkForceInline void SetSameAsMainMix()
Set channel config as the main mix channel configuration.
#define AK_SPEAKER_SETUP_5_1
AkChannelConfigType
Channel configuration type.
AkForceInline bool HasHeightChannels(AkChannelMask in_uChannelMask)
Returns true if standard configuration represented by channel mask has at least one "height" channel ...
#define AK_SPEAKER_SETUP_FRONT
static AkForceInline AkChannelConfig Object()
#define AK_SPEAKER_SETUP_7
7.0 setup channel mask
AkForceInline void SetObject()
Set channel config as an object-based configuration (implies dynamic number of objects).
#define AK_SPEAKER_SETUP_2_1
@ AK_ChannelConfigType_Anonymous
Channel mask == 0 and channels are anonymous.
AkForceInline bool HasSurroundChannels(AkChannelMask in_uChannelMask)
#define AK_SPEAKER_SETUP_2_0
AkForceInline bool operator==(const AkChannelConfig &in_other) const
Operator ==.
AkForceInline AkChannelConfig RemoveLFE() const
Returns a new config based on 'this' with no LFE.
AkForceInline void SetStandard(AkUInt32 in_uChannelMask)
Set channel config as a standard configuration specified with given channel mask.
#define AK_SPEAKER_FRONT_LEFT
Standard speakers (channel mask):
AkForceInline AkChannelConfig(AkUInt32 in_uNumChannels, AkUInt32 in_uChannelMask)
Constructor. Sets number of channels, and config type according to whether channel mask is defined or...
uint32_t AkUInt32
Unsigned 32-bit integer.
AkUInt32 eConfigType
Channel config type (AkChannelConfigType).
@ AK_ChannelConfigType_UseDeviceMain
Special setting for bus objects to use the audio device main configuration.
AkForceInline bool HasSideAndRearChannels(AkChannelMask in_uChannelMask)
AkForceInline bool HasLFE() const
static AkUInt8 ChannelMaskToNumChannels(AkChannelMask in_uChannelMask)
Returns the number of channels of a given channel configuration.
void AK_SPEAKER_SETUP_CONVERT_TO_SUPPORTED(AkUInt32 &io_uChannelMask)
AkChannelOrdering
Channel ordering type.
#define AK_SPEAKER_LOW_FREQUENCY
Low-frequency speaker bit mask.
AkForceInline void Deserialize(AkUInt32 in_uChannelConfig)
Deserialize channel config from a 32-bit word.
#define AK_SPEAKER_FRONT_CENTER
Front center speaker bit mask.
#define AkForceInline
Definition: AkTypes.h:63
void AK_SPEAKER_SETUP_FIX_LEFT_TO_CENTER(AkUInt32 &io_uChannelMask)
@ ChannelOrdering_RunTime
static AkForceInline AkChannelConfig Standard(AkUInt32 in_uChannelMask)
Construct standard channel config from channel mask.
AkForceInline bool IsValid() const
Returns true if valid, false otherwise (as when it is constructed, or invalidated using Clear()).
#define AK_SPEAKER_SETUP_4_0
#define AK_SPEAKER_BACK_RIGHT
Rear right speaker bit mask.
#define AK_SPEAKER_SIDE_RIGHT
Side right speaker bit mask.
AkForceInline bool HasStrictlyOnePairOfSurroundChannels(AkChannelMask in_uChannelMask)

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise