mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 07:13:57 +02:00
left/right channels of head shadow filter now have independent gain + implemented all-pass filter
This commit is contained in:
parent
e8c3125985
commit
0881959750
2 changed files with 56 additions and 20 deletions
|
@ -308,38 +308,37 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream*
|
|||
if (_enableFilter && shouldAttenuate) {
|
||||
|
||||
glm::vec3 relativePosition = streamToAdd->getPosition() - listeningNodeStream->getPosition();
|
||||
if (relativePosition.z < 0) { // if the source is behind us
|
||||
|
||||
if (relativePosition.z < 0) { // if the source is behind us
|
||||
AudioFilterHSF1s& penumbraFilter = streamToAdd->getFilter();
|
||||
|
||||
// calculate penumbra angle
|
||||
float headPenumbraAngle = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f),
|
||||
glm::normalize(relativePosition));
|
||||
|
||||
// normalize penumbra angle
|
||||
float normalizedHeadPenumbraAngle = headPenumbraAngle / PI_OVER_TWO;
|
||||
|
||||
if (normalizedHeadPenumbraAngle < EPSILON) {
|
||||
normalizedHeadPenumbraAngle = EPSILON;
|
||||
if (relativePosition.x < 0) {
|
||||
headPenumbraAngle *= -1.0f; // [-pi/2,+pi/2]
|
||||
}
|
||||
|
||||
const float SQUARE_ROOT_OF_TWO_OVER_TWO = 0.71f;
|
||||
const float SQUARE_ROOT_OF_TWO_OVER_TWO = 0.71f; // half power
|
||||
const float ONE_OVER_TWO_PI = 1.0f / TWO_PI;
|
||||
const float FILTER_CUTOFF_FREQUENCY_HZ = 4000.0f;
|
||||
float penumbraFilterGain;
|
||||
float penumbraFilterFrequency;
|
||||
float penumbraFilterSlope;
|
||||
|
||||
// calculate the updated gain. this will be tuned over time.
|
||||
// consider this only a crude-first pass at correlating gain, freq and slope with penumbra angle.
|
||||
penumbraFilterGain = SQUARE_ROOT_OF_TWO_OVER_TWO * (normalizedHeadPenumbraAngle + SQUARE_ROOT_OF_TWO_OVER_TWO);
|
||||
penumbraFilterFrequency = FILTER_CUTOFF_FREQUENCY_HZ; // constant frequency
|
||||
penumbraFilterSlope = SQUARE_ROOT_OF_TWO_OVER_TWO; // constant slope
|
||||
|
||||
qDebug() << "penumbra gain=" << penumbraFilterGain << ", penumbraAngle=" << normalizedHeadPenumbraAngle;
|
||||
// calculate the updated gain, frequency and slope. this will be tuned over time.
|
||||
const float penumbraFilterGainL = (-1.0f * ONE_OVER_TWO_PI * headPenumbraAngle ) + SQUARE_ROOT_OF_TWO_OVER_TWO;
|
||||
const float penumbraFilterGainR = (+1.0f * ONE_OVER_TWO_PI * headPenumbraAngle ) + SQUARE_ROOT_OF_TWO_OVER_TWO;
|
||||
const float penumbraFilterFrequency = FILTER_CUTOFF_FREQUENCY_HZ; // constant frequency
|
||||
const float penumbraFilterSlope = SQUARE_ROOT_OF_TWO_OVER_TWO; // constant slope
|
||||
|
||||
qDebug() << "penumbra gainL="
|
||||
<< penumbraFilterGainL
|
||||
<< "penumbra gainR="
|
||||
<< penumbraFilterGainR
|
||||
<< "penumbraAngle="
|
||||
<< headPenumbraAngle;
|
||||
|
||||
// set the gain on both filter channels
|
||||
penumbraFilter.setParameters(0, 0, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGain, penumbraFilterSlope);
|
||||
penumbraFilter.setParameters(0, 1, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGain, penumbraFilterSlope);
|
||||
penumbraFilter.setParameters(0, 0, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGainL, penumbraFilterSlope);
|
||||
penumbraFilter.setParameters(0, 1, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGainR, penumbraFilterSlope);
|
||||
|
||||
penumbraFilter.render(_clientSamples, _clientSamples, NETWORK_BUFFER_LENGTH_SAMPLES_STEREO / 2);
|
||||
}
|
||||
|
|
|
@ -236,6 +236,43 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Implements a all-pass filter using a biquad
|
||||
//
|
||||
class AudioFilterALL :
|
||||
public AudioFilter< AudioFilterALL >
|
||||
{
|
||||
public:
|
||||
|
||||
//
|
||||
// helpers
|
||||
//
|
||||
void updateKernel() {
|
||||
|
||||
const float omega = TWO_PI * _frequency / _sampleRate;
|
||||
const float cosOmega = cosf(omega);
|
||||
const float alpha = 0.5f * sinf(omega) / _slope;
|
||||
/*
|
||||
b0 = 1 - alpha
|
||||
b1 = -2*cos(w0)
|
||||
b2 = 1 + alpha
|
||||
a0 = 1 + alpha
|
||||
a1 = -2*cos(w0)
|
||||
a2 = 1 - alpha
|
||||
*/
|
||||
const float b0 = +1.0f - alpha;
|
||||
const float b1 = -2.0f * cosOmega;
|
||||
const float b2 = +1.0f + alpha;
|
||||
const float a0 = +1.0f + alpha;
|
||||
const float a1 = -2.0f * cosOmega;
|
||||
const float a2 = +1.0f - alpha;
|
||||
|
||||
const float normA0 = 1.0f / a0;
|
||||
|
||||
_kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Implements a single-band parametric EQ using a biquad "peaking EQ" configuration
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue