Version

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

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