103 float nyquist = 22050.0f);
140 float mClassicalAbsorption;
143 float mRelaxationTemperatureScale;
146 float mOxygenRelaxationFrequency;
149 float mNitrogenRelaxationFrequency;
152 float mOxygenRelaxationCoefficient;
155 float mNitrogenRelaxationCoefficient;
158 float mOxygenRelaxationFrequencyInv;
161 float mNitrogenRelaxationFrequencyInv;
187 static constexpr float weightingThresholdHz = 1000.0f;
199 const simd distanceToKnee = deltaLk / centerAbsorption;
203 .FrequencyBandLowerThirdCenters = lowerThirdCenters,
204 .CenterFrequencyAbsorption_dB = centerAbsorption,
205 .LowerThirdBandAbsorption_dB = lowerThirdAbsorption,
206 .HighFreqWeightedAbsorption_dB = weightedAbsorption,
210 .DistanceToKnee = distanceToKnee,
211 .LinearizedHFLossFactor = distanceToKnee * (centerAbsorption - lowerThirdAbsorption)
232 const simd linearizedHighBandLoss =
238 linearizedHighBandLoss,
239 centerFrequencyLoss);
263 const float f = frequencyHz;
264 const float f2 = f * f;
268 const float pr = 101.325f;
273 const float To = 20.0f + 273.15f;
276 const float To1 = 0.01f + 273.15f;
279 const float psat = pr *
::pow(10, -6.8346 *
::pow(To1 / T, 1.261f) + 4.6151f);
284 const float h = hr * (psat / pa);
287 const float frO = (pa / pr) * (24.0f + 4.04f *
::pow(10, 4) * h * ((0.02f + h) / (0.391f + h)));
290 const float frN = (pa / pr) *
::pow(T / To, -0.5f) * (9 + 280 * h *
::exp(-4.170 * (
::pow(T / To, -1.0f / 3.0f) - 1.0f)));
292 const float z = 0.1068f *
::exp(-3352 / T) *
::pow(frN + f2 / frN, -1);
294 const float y =
::pow(T / To, -2.5f) * (0.01275f *
::exp(-2239.1 / T) *
::pow(frO + f2 / frO, -1) + z);
310 const float referencePressureKPa = 101.325f;
312 const float referenceTemperatureK = 293.15f;
313 const float triplePointTemperatureK = 273.16f;
314 const float relativeTemperature = absoluteTemperatureK / referenceTemperatureK;
318 const float saturationVaporPressureKPa =
319 referencePressureKPa *
322 -6.8346f *
::pow(triplePointTemperatureK / absoluteTemperatureK, 1.261f) + 4.6151f);
325 const float waterVaporConcentrationPercent =
328 const float h = waterVaporConcentrationPercent;
330 mOxygenRelaxationFrequency =
334 ((0.02f + h) / (0.391f + h)));
336 mNitrogenRelaxationFrequency =
338 ::pow(relativeTemperature, -0.5f) *
340 280.0f * h *
::exp(-4.170f * (
::pow(relativeTemperature, -1.0f / 3.0f) - 1.0f)));
342 mClassicalAbsorption =
344 ::pow(relativePressure, -1.0f) *
345 ::sqrt(relativeTemperature);
347 mRelaxationTemperatureScale =
348 ::pow(relativeTemperature, -2.5f);
350 mOxygenRelaxationCoefficient =
352 ::exp(-2239.1f / absoluteTemperatureK);
354 mNitrogenRelaxationCoefficient =
356 ::exp(-3352.0f / absoluteTemperatureK);
358 mOxygenRelaxationFrequencyInv = 1.0f / mOxygenRelaxationFrequency;
359 mNitrogenRelaxationFrequencyInv = 1.0f / mNitrogenRelaxationFrequency;
364 const float f2 = frequencyHz * frequencyHz;
366 const float oxygenRelaxationAbsorption = mOxygenRelaxationCoefficient /
Math::FMA(f2, mOxygenRelaxationFrequencyInv, mOxygenRelaxationFrequency);
367 const float nitrogenRelaxationAbsorption = mNitrogenRelaxationCoefficient /
Math::FMA(f2, mNitrogenRelaxationFrequencyInv, mNitrogenRelaxationFrequency);
368 const float molecularRelaxationAbsorption = mRelaxationTemperatureScale * (oxygenRelaxationAbsorption + nitrogenRelaxationAbsorption);
369 const float totalAbsorptionBeforeFrequencyScale = mClassicalAbsorption + molecularRelaxationAbsorption;
376 const simd f2 = frequenciesHz * frequenciesHz;
378 const simd oxygenRelaxationAbsorption =
simd(mOxygenRelaxationCoefficient) /
Math::FMA(f2, mOxygenRelaxationFrequencyInv,
simd(mOxygenRelaxationFrequency));
379 const simd nitrogenRelaxationAbsorption =
simd(mNitrogenRelaxationCoefficient) /
Math::FMA(f2, mNitrogenRelaxationFrequencyInv,
simd(mNitrogenRelaxationFrequency));
380 const simd molecularRelaxationAbsorption =
simd(mRelaxationTemperatureScale) * (oxygenRelaxationAbsorption + nitrogenRelaxationAbsorption);
381 const simd totalAbsorptionBeforeFrequencyScale =
simd(mClassicalAbsorption) + molecularRelaxationAbsorption;
Definition AirAbsorption.h:97
static simd ComputeForDistance(float distance, const AirAbsorptionCache &aaCache)
Definition AirAbsorption.h:216
AirAbsorption(const AirAbsorptionParams ¶ms)
Definition AirAbsorption.h:308
static AbsorptionCoeffs ComputeForFrequencies(const FrequencyBands &frequenciesHz, const AirAbsorptionParams ¶ms)
Compute pure-tone sound attenuation in four frequency bands.
Definition AirAbsorption.h:302
static FrequencyBands ComputeHFWeightedBandCenters(const SplitFrequencies &splitFrequenciesHz)
Definition AirAbsorption.h:242
static float ComputeForFrequency(float frequencyHz, const AirAbsorptionParams ¶ms)
Definition AirAbsorption.h:259
float ComputeAbsorptionPerMeter(float frequencyHz) const
Compute pure-tone sound attenuation coefficient in dB/m, for atmospheric absorption.
Definition AirAbsorption.h:362
static AirAbsorptionCache CacheParameters(const FrequencyBands &frequencyBands, const AirAbsorptionParams ¶ms, float nyquist=22050.0f)
Definition AirAbsorption.h:178
static constexpr float ForTemperature(float temperatureC)
Definition SpeedOfSound.h:38
JPL_INLINE constexpr T FMA(T a, T b, T c) noexcept
Inlined fuse multiply-add. Compiler in some circumstances is more eager to optimize this than std::fm...
Definition Math.h:186
Definition AcousticMaterial.h:36
simd exp(simd x) noexcept
Exponent for 4-wide 32-bit float vector.
Definition SIMDMath.h:298
const FreqBandCenters cBandCenters
Definition FrequencyBands.h:89
constexpr float JPL_RECIP_M_TO_DB
Definition AirAbsorption.h:34
constexpr float JPL_DB_TO_RECIP_M
Definition AirAbsorption.h:31
JPL_INLINE SplitFrequencies SplitFrequenciesFromBandCenters(const FreqBandCenters &bandCenters, float nyquist=22050.0f)
Definition FrequencyBands.h:69
JPL_INLINE FreqBandCenters ComputeBandLowerThirdCenters(const SplitFrequencies &splitFrequenciesHz, float nyquist=22050.0f)
Definition FrequencyBands.h:58
JPL_INLINE simd round(const simd &vec) noexcept
Element-wise round to nearest integer value.
Definition SIMD.h:1930
simd pow(const simd &x, const simd &y) noexcept
Definition SIMDMath.h:372
JPL_INLINE FreqBandCenters ComputeBandCenters(const SplitFrequencies &splitFrequenciesHz, float nyquist=22050.0f)
Definition FrequencyBands.h:51
const AirAbsorptionCache cDefaultAirAbsCache
Default air absorption used in JPL Spatial.
Definition AirAbsorption.h:166
Definition AirAbsorption.h:53
const AbsorptionCoeffs HighFreqWeightedAbsorption_dB
Definition AirAbsorption.h:73
struct JPL::AirAbsorptionCache::@0 LinAprox
Linearized approximation for non-linear frequency loss by distance.
const simd_mask HasKnee
Definition AirAbsorption.h:83
const AbsorptionCoeffs FrequencyDecaySlope
Definition AirAbsorption.h:77
const simd LinearizedHFLossFactor
Definition AirAbsorption.h:85
const AbsorptionCoeffs LowerThirdBandAbsorption_dB
Definition AirAbsorption.h:66
const simd DistanceToKnee
Definition AirAbsorption.h:84
const AbsorptionCoeffs CenterFrequencyAbsorption_dB
Definition AirAbsorption.h:60
const FrequencyBands FrequencyBandLowerThirdCenters
Definition AirAbsorption.h:55
const FrequencyBands FrequencyBandCenters
Definition AirAbsorption.h:54
Definition AirAbsorption.h:40
float AtmosphericPressureKPa
Definition AirAbsorption.h:43
float RelativeHumidityPercent
Definition AirAbsorption.h:42
float AirTemperatureC
Definition AirAbsorption.h:41
Split frequencies points for crossover.
Definition FrequencyBands.h:41
Minimal 4-wide 32-bit float vector implementation for SIMD.
Definition SIMD.h:60
static JPL_INLINE simd select(const simd_mask &mask, const simd &a, const simd &b) noexcept
Component-wise select, returns 'a' if mask is true, 'b' otherwise.
Definition SIMD.h:1034