Version
menu_open
link
Wwise SDK 2021.1.14
AkReverbEstimation.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 Version: v2021.1.14 Build: 6590
25 Copyright (c) 2006-2023 Audiokinetic Inc.
26 *******************************************************************************/
27 
28 /// \file
29 /// Reverb parameter estimation.
30 
31 #pragma once
32 
36 
37 namespace AK {
38 namespace SpatialAudio {
39 
40 /// Audiokinetic reverb estimation namespace
41 namespace ReverbEstimation
42 {
43  ////////////////////////////////////////////////////////////////////////
44  /// @name Reverb estimation.
45  /// These functions can be used to estimate the reverb parameters of a physical environment, using its volume and surface area
46  //@{
47 
48  /// This is used to estimate the line of best fit through the absorption values of an Acoustic Texture.
49  /// This value is what's known as the HFDamping.
50  /// return Gradient of line of best fit through y = mx + c.
51  float CalculateSlope(const AkAcousticTexture& texture)
52  {
53  // constants for the mean and standard deviation of the acoustic texture indices 0,1,2,3
54  const float meanX = 1.5f;
55  const float sdX = 1.11803399;
56 
57  const int N = 4;
58  float meanY = (texture.fAbsorptionLow + texture.fAbsorptionMidLow + texture.fAbsorptionMidHigh + texture.fAbsorptionHigh) / (float)N;
59  float absorptions[4] = { texture.fAbsorptionLow, texture.fAbsorptionMidLow, texture.fAbsorptionMidHigh, texture.fAbsorptionHigh };
60  float sdY = 0.0f;
61  float meanDiffDotProd = 0.0f;
62  for (int i = 0; i < N; ++i)
63  {
64  const float yMeanDiff = absorptions[i] - meanY;
65  const float xMeanDiff = (float)i - meanX;
66  meanDiffDotProd += yMeanDiff * xMeanDiff;
67  sdY += yMeanDiff * yMeanDiff;
68  }
69  if (sdY == 0.0f)
70  return 0.0f;
71  sdY = sqrtf(sdY / (float)N);
72  const float correlationCoeff = (1.0f / (N - 1.0f)) * (meanDiffDotProd / (sdY * sdX));
73  return correlationCoeff * (sdY / sdX);
74  }
75 
76  /// Calculate average absorption values using each of the textures in in_textures, weighted by their corresponding surface area.
77  void GetAverageAbsorptionValues(AkAcousticTexture* in_textures, float* in_surfaceAreas, int in_numTextures, AkAcousticTexture& out_average)
78  {
79  float surfaceArea = 0.0f;
80  float totalSurfaceArea = 0.0f;
81  out_average.fAbsorptionLow = 0.0f;
82  out_average.fAbsorptionMidLow = 0.0f;
83  out_average.fAbsorptionMidHigh = 0.0f;
84  out_average.fAbsorptionHigh = 0.0f;
85  for (int textureIndex = 0; textureIndex < in_numTextures; ++textureIndex)
86  {
87  AkAcousticTexture& texture = in_textures[textureIndex];
88  surfaceArea = in_surfaceAreas[textureIndex];
89  out_average.fAbsorptionLow += texture.fAbsorptionLow * surfaceArea;
90  out_average.fAbsorptionMidLow += texture.fAbsorptionMidLow * surfaceArea;
91  out_average.fAbsorptionMidHigh += texture.fAbsorptionMidHigh * surfaceArea;
92  out_average.fAbsorptionHigh += texture.fAbsorptionHigh * surfaceArea;
93  totalSurfaceArea += surfaceArea;
94  }
95  AKASSERT(totalSurfaceArea > 0.0f);
96  out_average.fAbsorptionLow = out_average.fAbsorptionLow / totalSurfaceArea;
97  out_average.fAbsorptionMidLow = out_average.fAbsorptionMidLow / totalSurfaceArea;
98  out_average.fAbsorptionMidHigh = out_average.fAbsorptionMidHigh / totalSurfaceArea;
99  out_average.fAbsorptionHigh = out_average.fAbsorptionHigh / totalSurfaceArea;
100  }
101 
102  /// Estimate the time taken (in seconds) for the sound reverberation in a physical environment to decay by 60 dB.
103  /// This is estimated using the Sabine equation. The T60 decay time can be used to drive the decay parameter of a reverb effect.
105  AkReal32 in_volumeCubicMeters, ///< The volume (in cubic meters) of the physical environment. 0 volume or negative volume will give a decay estimate of 0.
106  AkReal32 in_surfaceAreaSquaredMeters, ///< The surface area (in squared meters) of the physical environment. Must be >= AK_SA_MIN_ENVIRONMENT_SURFACE_AREA
107  AkReal32 in_environmentAverageAbsorption, ///< The average absorption amount of the surfaces in the environment. Must be between AK_SA_MIN_ENVIRONMENT_ABSORPTION and 1.
108  AkReal32& out_decayEstimate ///< Returns the time taken (in seconds) for the reverberation to decay bu 60 dB.
109  )
110  {
111  if (in_volumeCubicMeters <= 0.0f)
112  {
113  out_decayEstimate = 0.0f;
114  return AKRESULT::AK_Success;
115  }
116  if (in_surfaceAreaSquaredMeters < AK_SA_MIN_ENVIRONMENT_SURFACE_AREA)
117  {
118  AKASSERT(false && "AK::SpatialAudio::ReverbEstimation::EstimateT60Decay: Invalid surface area. in_SurfaceAreaSquaredMeters Must be >= AK_SA_MIN_ENVIRONMENT_SURFACE_AREA");
119  return AKRESULT::AK_Fail;
120  }
121  if (in_environmentAverageAbsorption < AK_SA_MIN_ENVIRONMENT_ABSORPTION || in_environmentAverageAbsorption > 1.0f)
122  {
123  AKASSERT(false && "AK::SpatialAudio::ReverbEstimation::EstimateT60Decay: Invalid absorption value. in_EnvironmentAverageAbsorption Must be between AK_SA_MIN_ENVIRONMENT_ABSORPTION and 1");
124  return AKRESULT::AK_Fail;
125  }
126  // The Sabine equation.
127  out_decayEstimate = (0.161f * in_volumeCubicMeters) / (in_surfaceAreaSquaredMeters * in_environmentAverageAbsorption);
128  return AKRESULT::AK_Success;
129  }
130 
131  /// Estimate the time taken (in milliseconds) for the first reflection to reach the listener.
132  /// This assumes the emitter and listener are both positioned in the centre of the environment.
134  AkVector in_environmentExtentMeters, ///< Defines the dimensions of the environment (in meters) relative to the center; all components must be positive numbers.
135  AkReal32& out_timeToFirstReflectionMs, ///< Returns the time taken (in milliseconds) for the first reflection to reach the listener.
136  AkReal32 in_speedOfSound = 343.0f ///< Defaults to 343.0 - the speed of sound in dry air. Must be > 0.
137  )
138  {
139  if (in_speedOfSound <= 0.0f)
140  {
141  AKASSERT(false && "AK::SpatialAudio::ReverbEstimation::EstimateTimeToFirstReflection: Invalid speed of sound. in_speedOfSound must be greater than 0.");
142  return AKRESULT::AK_Fail;
143  }
144  if (in_environmentExtentMeters.X < 0.0f || in_environmentExtentMeters.Y < 0.0f || in_environmentExtentMeters.Z < 0.0f)
145  {
146  AKASSERT(false && "AK::SpatialAudio::ReverbEstimation::EstimateTimeToFirstReflection: Invalid extent. All components must be positive numbers.");
147  return AKRESULT::AK_Fail;
148  }
149  const float minDimension = AkMin(AkMin(in_environmentExtentMeters.X, in_environmentExtentMeters.Y), in_environmentExtentMeters.Z);
150  out_timeToFirstReflectionMs = minDimension / in_speedOfSound;
151  return AKRESULT::AK_Success;
152  }
153 
154  /// Estimate the high frequency damping from a collection of AkAcousticTextures and corresponding surface areas.
155  /// The high frequency damping is a measure of how much high frequencies are dampened compared to low frequencies. > 0 indicates more high frequency damping than low frequency damping. < 0 indicates more low frequency damping than high frequency damping. 0 indicates uniform damping.
156  /// The average absorption values are calculated using each of the textures in the collection, weighted by their corresponding surface area.
157  /// The HFDamping is then calculated as the line-of-best-fit through the average absorption values.
159  AkAcousticTexture* in_textures, ///< A collection of AkAcousticTexture structs from which to calculate the average high frequency damping.
160  float* in_surfaceAreas, ///< Surface area values for each of the textures in in_textures.
161  int in_numTextures, ///< The number of textures in in_textures (and the number of surface area values in in_surfaceAreas).
162  AkReal32& out_hfDamping ///< Returns the high frequency damping value. > 0 indicates more high frequency damping than low frequency damping. < 0 indicates more low frequency damping than high frequency damping. 0 indicates uniform damping.
163  )
164  {
165  if (in_textures == nullptr || in_surfaceAreas == nullptr || in_numTextures == 0)
166  {
167  out_hfDamping = 0.0f;
168  return AK_Success;
169  }
170  AkAcousticTexture averageAbsorptionValues;
171  GetAverageAbsorptionValues(in_textures, in_surfaceAreas, in_numTextures, averageAbsorptionValues);
172  out_hfDamping = CalculateSlope(averageAbsorptionValues);
173  return AK_Success;
174  }
175 
176  //@}
177 }
178 }
179 }
#define AkMin(x1, x2)
Definition: AkPlatformFuncs.h:94
float AkReal32
32-bit floating point
Definition: AkTypes.h:70
AKSOUNDENGINE_API AKRESULT EstimateHFDamping(AkAcousticTexture *in_textures, float *in_surfaceAreas, int in_numTextures, AkReal32 &out_hfDamping)
Audiokinetic namespace.
@ AK_Fail
The operation failed.
Definition: AkTypes.h:135
#define AK_EXTERNAPIFUNC(_type, _name)
AKRESULT
Standard function call result.
Definition: AkTypes.h:132
AkReal32 fAbsorptionHigh
AkReal32 fAbsorptionMidHigh
AKSOUNDENGINE_API AKRESULT EstimateT60Decay(AkReal32 in_volumeCubicMeters, AkReal32 in_surfaceAreaSquaredMeters, AkReal32 in_environmentAverageAbsorption, AkReal32 &out_decayEstimate)
@ AK_Success
The operation was successful.
Definition: AkTypes.h:134
AKSOUNDENGINE_API AKRESULT EstimateTimeToFirstReflection(AkVector in_environmentExtentMeters, AkReal32 &out_timeToFirstReflectionMs, AkReal32 in_speedOfSound=343.0f)
#define AK_SA_MIN_ENVIRONMENT_SURFACE_AREA
AkReal32 Y
Y Position.
Definition: AkTypes.h:340
float CalculateSlope(const AkAcousticTexture &texture)
AkReal32 X
X Position.
Definition: AkTypes.h:339
#define AKASSERT(Condition)
Definition: AkAssert.h:76
AkReal32 Z
Z Position.
Definition: AkTypes.h:341
void GetAverageAbsorptionValues(AkAcousticTexture *in_textures, float *in_surfaceAreas, int in_numTextures, AkAcousticTexture &out_average)
Calculate average absorption values using each of the textures in in_textures, weighted by their corr...
AkReal32 fAbsorptionMidLow
3D vector.
Definition: AkTypes.h:311
AkReal32 fAbsorptionLow

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