Version

menu_open
Wwise SDK 2023.1.9
AkSpeakerVolumes.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) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 // AkSpeakerVolumes.h
28 
29 /// \file
30 /// Multi-channel volume definitions and services.
31 /// Always associated with an AkChannelConfig. In the case of standard configurations, the volume items ordering
32 /// match the bit ordering in the channel mask, except for the LFE which is skipped and placed at the end of the
33 /// volume array.
34 /// Refer to \ref goingfurther_speakermatrixcallback for an example of how to manipulate speaker volume vectors/matrices.
35 
36 #ifndef _AK_SPEAKER_VOLUMES_H_
37 #define _AK_SPEAKER_VOLUMES_H_
38 
40 #include <AK/SoundEngine/Platforms/Generic/AkSpeakerVolumes.h>
43 
44 namespace AK
45 {
46 /// Multi-channel volume definitions and services.
47 namespace SpeakerVolumes
48 {
49  typedef AkReal32 * VectorPtr; ///< Volume vector. Access each element with the standard bracket [] operator.
50  typedef AkReal32 * MatrixPtr; ///< Volume matrix. Access each input channel vector with AK::SpeakerVolumes::Matrix::GetChannel().
51  typedef const AkReal32 * ConstVectorPtr; ///< Constant volume vector. Access each element with the standard bracket [] operator.
52  typedef const AkReal32 * ConstMatrixPtr; ///< Constant volume matrix. Access each input channel vector with AK::SpeakerVolumes::Matrix::GetChannel().
53 
54  /// Volume vector services.
55  namespace Vector
56  {
57  /// Copy volumes.
58  AkForceInline void Copy( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels )
59  {
60  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
61  if ( in_uNumChannels )
62  memcpy( in_pVolumesDst, in_pVolumesSrc, in_uNumChannels * sizeof( AkReal32 ) );
63  }
64 
65  /// Copy volumes with gain.
66  AkForceInline void Copy( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels, AkReal32 in_fGain )
67  {
68  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
69  for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
70  {
71  in_pVolumesDst[uChan] = in_pVolumesSrc[uChan] * in_fGain;
72  }
73  }
74 
75  /// Clear volumes.
76  AkForceInline void Zero( VectorPtr in_pVolumes, AkUInt32 in_uNumChannels )
77  {
78  AKASSERT( in_pVolumes || in_uNumChannels == 0 );
79  if ( in_uNumChannels )
80  memset( in_pVolumes, 0, in_uNumChannels * sizeof( AkReal32 ) );
81  }
82 
83  /// Accumulate two volume vectors.
84  AkForceInline void Add( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels )
85  {
86  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
87  for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
88  {
89  in_pVolumesDst[uChan] += in_pVolumesSrc[uChan];
90  }
91  }
92 
93  /// Compute the sum of all components of a volume vector.
94  AkForceInline AkReal32 L1Norm(ConstVectorPtr io_pVolumes, AkUInt32 in_uNumChannels)
95  {
96  AkReal32 total = 0;
97  AKASSERT((io_pVolumes) || in_uNumChannels == 0);
98  for (AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++)
99  {
100  total += io_pVolumes[uChan];
101  }
102 
103  return total;
104  }
105 
106  /// Multiply volume vector with a scalar.
107  AkForceInline void Mul( VectorPtr in_pVolumesDst, const AkReal32 in_fVol, AkUInt32 in_uNumChannels )
108  {
109  AKASSERT( in_pVolumesDst || in_uNumChannels == 0 );
110  for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
111  {
112  in_pVolumesDst[uChan] *= in_fVol;
113  }
114  }
115 
116  /// Multiply two volume vectors.
117  AkForceInline void Mul( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels )
118  {
119  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
120  for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
121  {
122  in_pVolumesDst[uChan] *= in_pVolumesSrc[uChan];
123  }
124  }
125 
126  /// Get max for all elements of two volume vectors, independently.
127  AkForceInline void Max( AkReal32 * in_pVolumesDst, const AkReal32 * in_pVolumesSrc, AkUInt32 in_uNumChannels )
128  {
129  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
130  for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
131  {
132  in_pVolumesDst[uChan] = AkMax( in_pVolumesDst[uChan], in_pVolumesSrc[uChan] );
133  }
134  }
135 
136  /// Get min for all elements of two volume vectors, independently.
137  AkForceInline void Min( AkReal32 * in_pVolumesDst, const AkReal32 * in_pVolumesSrc, AkUInt32 in_uNumChannels )
138  {
139  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
140  for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
141  {
142  in_pVolumesDst[uChan] = AkMin( in_pVolumesDst[uChan], in_pVolumesSrc[uChan] );
143  }
144  }
145  }
146 
147  /// Volume matrix (multi-in/multi-out channel configurations) services.
148  namespace Matrix
149  {
150  /// Compute size (in bytes) required for given channel configurations.
151  AkForceInline AkUInt32 GetRequiredSize( AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
152  {
153  return in_uNumChannelsIn * Vector::GetRequiredSize( in_uNumChannelsOut );
154  }
155 
156  /// Compute size (in number of elements) required for given channel configurations.
157  AkForceInline AkUInt32 GetNumElements( AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
158  {
159  return in_uNumChannelsIn * Vector::GetNumElements( in_uNumChannelsOut );
160  }
161 
162  /// Get pointer to volume distribution for input channel in_uIdxChannelIn.
163  AkForceInline VectorPtr GetChannel( MatrixPtr in_pVolumeMx, AkUInt32 in_uIdxChannelIn, AkUInt32 in_uNumChannelsOut )
164  {
165  AKASSERT( in_pVolumeMx );
166  return in_pVolumeMx + in_uIdxChannelIn * Vector::GetNumElements( in_uNumChannelsOut );
167  }
168 
169  /// Get pointer to volume distribution for input channel in_uIdxChannelIn.
170  AkForceInline ConstVectorPtr GetChannel( ConstMatrixPtr in_pVolumeMx, AkUInt32 in_uIdxChannelIn, AkUInt32 in_uNumChannelsOut )
171  {
172  AKASSERT( in_pVolumeMx );
173  return in_pVolumeMx + in_uIdxChannelIn * Vector::GetNumElements( in_uNumChannelsOut );
174  }
175 
176  /// Copy matrix.
177  AkForceInline void Copy( MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
178  {
179  AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
180  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || uNumElements == 0 );
181  if ( uNumElements )
182  memcpy( in_pVolumesDst, in_pVolumesSrc, uNumElements * sizeof( AkReal32 ) );
183  }
184 
185  /// Copy matrix with gain.
186  AkForceInline void Copy( MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut, AkReal32 in_fGain )
187  {
188  AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
189  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || uNumElements == 0 );
190  for ( AkUInt32 uChan = 0; uChan < uNumElements; uChan++ )
191  {
192  in_pVolumesDst[uChan] = in_pVolumesSrc[uChan] * in_fGain;
193  }
194  }
195 
196  /// Clear matrix.
197  AkForceInline void Zero( MatrixPtr in_pVolumes, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
198  {
199  AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
200  AKASSERT( in_pVolumes || uNumElements == 0 );
201  if ( uNumElements )
202  memset( in_pVolumes, 0, uNumElements * sizeof( AkReal32 ) );
203  }
204 
205  /// Multiply a matrix with a scalar.
206  AkForceInline void Mul( MatrixPtr in_pVolumesDst, const AkReal32 in_fVol, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
207  {
208  AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
209  AKASSERT( in_pVolumesDst || uNumElements == 0 );
210  for ( AkUInt32 uChan = 0; uChan < uNumElements; uChan++ )
211  {
212  in_pVolumesDst[uChan] *= in_fVol;
213  }
214  }
215 
216  /// Add all elements of two volume matrices, independently.
217  AkForceInline void Add(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
218  {
219  AkUInt32 uNumElements = Matrix::GetNumElements(in_uNumChannelsIn, in_uNumChannelsOut);
220  AKASSERT((in_pVolumesDst && in_pVolumesSrc) || uNumElements == 0);
221  for (AkUInt32 uChan = 0; uChan < uNumElements; uChan++)
222  {
223  in_pVolumesDst[uChan] += in_pVolumesSrc[uChan];
224  }
225  }
226 
227  /// Pointwise Multiply-Add of all elements of two volume matrices.
228  AkForceInline void MAdd(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut, AkReal32 in_fGain)
229  {
230  AkUInt32 uNumElements = Matrix::GetNumElements(in_uNumChannelsIn, in_uNumChannelsOut);
231  AKASSERT((in_pVolumesDst && in_pVolumesSrc) || uNumElements == 0);
232  for (AkUInt32 uChan = 0; uChan < uNumElements; uChan++)
233  {
234  in_pVolumesDst[uChan] += in_pVolumesSrc[uChan] * in_fGain;
235  }
236  }
237 
238  /// Get absolute max for all elements of two volume matrices, independently.
239  AkForceInline void AbsMax(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
240  {
241  AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
242  AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || uNumElements == 0 );
243  for ( AkUInt32 uChan = 0; uChan < uNumElements; uChan++ )
244  {
245  in_pVolumesDst[uChan] = ((in_pVolumesDst[uChan] * in_pVolumesDst[uChan]) > (in_pVolumesSrc[uChan] * in_pVolumesSrc[uChan])) ? in_pVolumesDst[uChan] : in_pVolumesSrc[uChan];
246  }
247  }
248 
249  /// Get max for all elements of two volume matrices, independently.
250  AkForceInline void Max(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
251  {
252  AkUInt32 uNumElements = Matrix::GetNumElements(in_uNumChannelsIn, in_uNumChannelsOut);
253  AKASSERT((in_pVolumesDst && in_pVolumesSrc) || uNumElements == 0);
254  for (AkUInt32 uChan = 0; uChan < uNumElements; uChan++)
255  {
256  in_pVolumesDst[uChan] = (in_pVolumesDst[uChan] > in_pVolumesSrc[uChan]) ? in_pVolumesDst[uChan] : in_pVolumesSrc[uChan];
257  }
258  }
259  }
260 }
261 }
262 
263 #endif //_AK_SPEAKER_VOLUMES_H_
#define AkMin(x1, x2)
AkForceInline void Copy(VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels)
Copy volumes.
Audiokinetic namespace.
#define AkMax(x1, x2)
AkForceInline AkReal32 L1Norm(ConstVectorPtr io_pVolumes, AkUInt32 in_uNumChannels)
Compute the sum of all components of a volume vector.
AkForceInline void Max(AkReal32 *in_pVolumesDst, const AkReal32 *in_pVolumesSrc, AkUInt32 in_uNumChannels)
Get max for all elements of two volume vectors, independently.
AkForceInline AkUInt32 GetRequiredSize(AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Compute size (in bytes) required for given channel configurations.
AkForceInline void Zero(MatrixPtr in_pVolumes, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Clear matrix.
AkForceInline AkUInt32 GetNumElements(AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Compute size (in number of elements) required for given channel configurations.
float AkReal32
32-bit floating point
AkForceInline void AbsMax(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Get absolute max for all elements of two volume matrices, independently.
AkReal32 * VectorPtr
Volume vector. Access each element with the standard bracket [] operator.
AkForceInline VectorPtr GetChannel(MatrixPtr in_pVolumeMx, AkUInt32 in_uIdxChannelIn, AkUInt32 in_uNumChannelsOut)
Get pointer to volume distribution for input channel in_uIdxChannelIn.
#define AKASSERT(Condition)
Definition: AkAssert.h:67
AkForceInline void Add(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Add all elements of two volume matrices, independently.
const AkReal32 * ConstMatrixPtr
Constant volume matrix. Access each input channel vector with AK::SpeakerVolumes::Matrix::GetChannel(...
AkForceInline void Zero(VectorPtr in_pVolumes, AkUInt32 in_uNumChannels)
Clear volumes.
AkForceInline void MAdd(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut, AkReal32 in_fGain)
Pointwise Multiply-Add of all elements of two volume matrices.
AkForceInline void Add(VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels)
Accumulate two volume vectors.
AkReal32 * MatrixPtr
Volume matrix. Access each input channel vector with AK::SpeakerVolumes::Matrix::GetChannel().
AkForceInline void Mul(MatrixPtr in_pVolumesDst, const AkReal32 in_fVol, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Multiply a matrix with a scalar.
uint32_t AkUInt32
Unsigned 32-bit integer.
AkForceInline void Copy(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Copy matrix.
AkForceInline void Max(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Get max for all elements of two volume matrices, independently.
#define AkForceInline
Definition: AkTypes.h:63
const AkReal32 * ConstVectorPtr
Constant volume vector. Access each element with the standard bracket [] operator.
AkForceInline void Min(AkReal32 *in_pVolumesDst, const AkReal32 *in_pVolumesSrc, AkUInt32 in_uNumChannels)
Get min for all elements of two volume vectors, independently.
AkForceInline void Mul(VectorPtr in_pVolumesDst, const AkReal32 in_fVol, AkUInt32 in_uNumChannels)
Multiply volume vector with a scalar.

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