mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 853360 - Implement the coneGain part of the AudioPannerNode. r=roc
--HG-- extra : rebase_source : c3a27ef2da8a080b9b310af14cf85f68f13df9a6
This commit is contained in:
parent
9e83a59dad
commit
f3581fffe3
@ -117,7 +117,8 @@ public:
|
||||
}
|
||||
|
||||
void ComputeAzimuthAndElevation(float& aAzimuth, float& aElevation);
|
||||
void DistanceGain(AudioChunk* aChunk, float aGain);
|
||||
void DistanceAndConeGain(AudioChunk* aChunk, float aGain);
|
||||
float ComputeConeGain();
|
||||
|
||||
void GainMonoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
|
||||
float aGainL, float aGainR);
|
||||
@ -226,7 +227,7 @@ void
|
||||
PannerNodeEngine::EqualPowerPanningFunction(const AudioChunk& aInput,
|
||||
AudioChunk* aOutput)
|
||||
{
|
||||
float azimuth, elevation, gainL, gainR, normalizedAzimuth, distance, distanceGain;
|
||||
float azimuth, elevation, gainL, gainR, normalizedAzimuth, distance, distanceGain, coneGain;
|
||||
int inputChannels = aInput.mChannelData.Length();
|
||||
ThreeDPoint distanceVec;
|
||||
|
||||
@ -242,6 +243,7 @@ PannerNodeEngine::EqualPowerPanningFunction(const AudioChunk& aInput,
|
||||
AllocateAudioBlock(2, aOutput);
|
||||
|
||||
ComputeAzimuthAndElevation(azimuth, elevation);
|
||||
coneGain = ComputeConeGain();
|
||||
|
||||
// The following algorithm is described in the spec.
|
||||
// Clamp azimuth in the [-90, 90] range.
|
||||
@ -281,7 +283,7 @@ PannerNodeEngine::EqualPowerPanningFunction(const AudioChunk& aInput,
|
||||
GainStereoToStereo(aInput, aOutput, gainL, gainR, azimuth);
|
||||
}
|
||||
|
||||
DistanceGain(aOutput, distanceGain);
|
||||
DistanceAndConeGain(aOutput, distanceGain * coneGain);
|
||||
}
|
||||
|
||||
void
|
||||
@ -308,7 +310,7 @@ PannerNodeEngine::GainStereoToStereo(const AudioChunk& aInput, AudioChunk* aOutp
|
||||
}
|
||||
|
||||
void
|
||||
PannerNodeEngine::DistanceGain(AudioChunk* aChunk, float aGain)
|
||||
PannerNodeEngine::DistanceAndConeGain(AudioChunk* aChunk, float aGain)
|
||||
{
|
||||
float* samples = static_cast<float*>(const_cast<void*>(*aChunk->mChannelData.Elements()));
|
||||
uint32_t channelCount = aChunk->mChannelData.Length();
|
||||
@ -371,6 +373,48 @@ PannerNodeEngine::ComputeAzimuthAndElevation(float& aAzimuth, float& aElevation)
|
||||
}
|
||||
}
|
||||
|
||||
// This algorithm is described in the WebAudio spec.
|
||||
float
|
||||
PannerNodeEngine::ComputeConeGain()
|
||||
{
|
||||
// Omnidirectional source
|
||||
if (mOrientation.IsZero() || ((mConeInnerAngle == 360) && (mConeOuterAngle == 360))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Normalized source-listener vector
|
||||
ThreeDPoint sourceToListener = mListenerPosition - mPosition;
|
||||
sourceToListener.Normalize();
|
||||
|
||||
ThreeDPoint normalizedSourceOrientation = mOrientation;
|
||||
normalizedSourceOrientation.Normalize();
|
||||
|
||||
// Angle between the source orientation vector and the source-listener vector
|
||||
double dotProduct = sourceToListener.DotProduct(normalizedSourceOrientation);
|
||||
double angle = 180 * acos(dotProduct) / M_PI;
|
||||
double absAngle = fabs(angle);
|
||||
|
||||
// Divide by 2 here since API is entire angle (not half-angle)
|
||||
double absInnerAngle = fabs(mConeInnerAngle) / 2;
|
||||
double absOuterAngle = fabs(mConeOuterAngle) / 2;
|
||||
double gain = 1;
|
||||
|
||||
if (absAngle <= absInnerAngle) {
|
||||
// No attenuation
|
||||
gain = 1;
|
||||
} else if (absAngle >= absOuterAngle) {
|
||||
// Max attenuation
|
||||
gain = mConeOuterGain;
|
||||
} else {
|
||||
// Between inner and outer cones
|
||||
// inner -> outer, x goes from 0 -> 1
|
||||
double x = (absAngle - absInnerAngle) / (absOuterAngle - absInnerAngle);
|
||||
gain = (1 - x) + mConeOuterGain * x;
|
||||
}
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user