diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 85ce208548..0e59f7b702 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -275,7 +275,7 @@ void AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream* glm::vec3 relativePosition = streamToAdd->getPosition() - listeningNodeStream->getPosition(); if (relativePosition.z < 0) { // if the source is behind us - AudioFilterPEQ1s& penumbraFilter = streamToAdd->getFilter(); + AudioFilterHSF1s& penumbraFilter = streamToAdd->getFilter(); // calculate penumbra angle float headPenumbraAngle = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f), @@ -288,14 +288,17 @@ void AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream* normalizedHeadPenumbraAngle = EPSILON; } + const float SQUARE_ROOT_OF_TWO_OVER_TWO = 0.71f; + const float FILTER_CUTOFF_FREQUENCY_HZ = 4000.0f; float penumbraFilterGain; float penumbraFilterFrequency; float penumbraFilterSlope; - - // calculate the updated gain - penumbraFilterGain = normalizedHeadPenumbraAngle; // Note this will be tuned - consider this only a crude-first pass at correlating gain with penumbra angle. - penumbraFilterFrequency = 2000.0f; - penumbraFilterSlope = 1.0f; // gentle slope + + // 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; diff --git a/libraries/audio/src/AudioFilter.h b/libraries/audio/src/AudioFilter.h index 408a713db7..7c3c98582b 100644 --- a/libraries/audio/src/AudioFilter.h +++ b/libraries/audio/src/AudioFilter.h @@ -95,7 +95,7 @@ public: // Implements common base class interface for all Audio Filter Objects // template< class T > -class AudioFilterBase { +class AudioFilter { protected: @@ -119,11 +119,11 @@ public: // // ctor/dtor // - AudioFilterBase() { + AudioFilter() { setParameters(0.,0.,0.,0.); } - ~AudioFilterBase() { + ~AudioFilter() { } // @@ -156,7 +156,7 @@ public: // Implements a low-shelf filter using a biquad // class AudioFilterLSF : -public AudioFilterBase< AudioFilterLSF > +public AudioFilter< AudioFilterLSF > { public: @@ -164,7 +164,33 @@ public: // helpers // void updateKernel() { - // TBD + + const float a = _gain; + const float aAdd1 = a + 1.0f; + const float aSub1 = a - 1.0f; + const float omega = TWO_PI * _frequency / _sampleRate; + const float aAdd1TimesCosOmega = aAdd1 * cosf(omega); + const float aSub1TimesCosOmega = aSub1 * cosf(omega); + const float alpha = 0.5f * sinf(omega) / _slope; + const float zeta = 2.0f * sqrtf(a) * alpha; + /* + b0 = A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha ) + b1 = 2*A*( (A-1) - (A+1)*cos(w0) ) + b2 = A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha ) + a0 = (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha + a1 = -2*( (A-1) + (A+1)*cos(w0) ) + a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha + */ + const float b0 = +1.0f * (aAdd1 - aSub1TimesCosOmega + zeta) * a; + const float b1 = +2.0f * (aSub1 - aAdd1TimesCosOmega + ZERO) * a; + const float b2 = +1.0f * (aAdd1 - aSub1TimesCosOmega - zeta) * a; + const float a0 = +1.0f * (aAdd1 + aSub1TimesCosOmega + zeta); + const float a1 = -2.0f * (aSub1 + aAdd1TimesCosOmega + ZERO); + const float a2 = +1.0f * (aAdd1 + aSub1TimesCosOmega - zeta); + + const float normA0 = 1.0f / a0; + + _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } }; @@ -172,7 +198,7 @@ public: // Implements a hi-shelf filter using a biquad // class AudioFilterHSF : -public AudioFilterBase< AudioFilterHSF > +public AudioFilter< AudioFilterHSF > { public: @@ -180,7 +206,33 @@ public: // helpers // void updateKernel() { - // TBD + + const float a = _gain; + const float aAdd1 = a + 1.0f; + const float aSub1 = a - 1.0f; + const float omega = TWO_PI * _frequency / _sampleRate; + const float aAdd1TimesCosOmega = aAdd1 * cosf(omega); + const float aSub1TimesCosOmega = aSub1 * cosf(omega); + const float alpha = 0.5f * sinf(omega) / _slope; + const float zeta = 2.0f * sqrtf(a) * alpha; + /* + b0 = A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha ) + b1 = -2*A*( (A-1) + (A+1)*cos(w0) ) + b2 = A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha ) + a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha + a1 = 2*( (A-1) - (A+1)*cos(w0) ) + a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha + */ + const float b0 = +1.0f * (aAdd1 + aSub1TimesCosOmega + zeta) * a; + const float b1 = -2.0f * (aSub1 + aAdd1TimesCosOmega + ZERO) * a; + const float b2 = +1.0f * (aAdd1 + aSub1TimesCosOmega - zeta) * a; + const float a0 = +1.0f * (aAdd1 - aSub1TimesCosOmega + zeta); + const float a1 = +2.0f * (aSub1 - aAdd1TimesCosOmega + ZERO); + const float a2 = +1.0f * (aAdd1 - aSub1TimesCosOmega - zeta); + + const float normA0 = 1.0f / a0; + + _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } }; @@ -188,7 +240,7 @@ public: // Implements a single-band parametric EQ using a biquad "peaking EQ" configuration // class AudioFilterPEQ : - public AudioFilterBase< AudioFilterPEQ > + public AudioFilter< AudioFilterPEQ > { public: @@ -197,26 +249,30 @@ public: // void updateKernel() { - const float a = _gain; - const float omega = TWO_PI * _frequency / _sampleRate; - const float alpha = 0.5f * sinf(omega) / _slope; - + const float a = _gain; + const float omega = TWO_PI * _frequency / _sampleRate; + const float cosOmega = cosf(omega); + const float alpha = 0.5f * sinf(omega) / _slope; + const float alphaMulA = alpha * a; + const float alphaDivA = alpha / a; /* - a0 = 1 + alpha*A - a1 = -2*cos(w0) - a2 = 1 - alpha*A + b0 = 1 + alpha*A b1 = -2*cos(w0) - b2 = 1 - alpha/A + b2 = 1 - alpha*A + a0 = 1 + alpha/A + a1 = -2*cos(w0) + a2 = 1 - alpha/A */ - const float a0 = 1.0f + (alpha * a); - const float a1 = -2.0f * cosf(omega); - const float a2 = 1.0f - (alpha * a); - const float b1 = a1; - const float b2 = 1.0f - (alpha / a); + const float b0 = +1.0f + alphaMulA; + const float b1 = -2.0f * cosOmega; + const float b2 = +1.0f - alphaMulA; + const float a0 = +1.0f + alphaDivA; + const float a1 = -2.0f * cosOmega; + const float a2 = +1.0f - alphaDivA; - const float scale = 1.0f / (1.0f + (alpha / a)); + const float normA0 = 1.0f / a0; - _kernel.setParameters(a0 * scale, a1 * scale, a2 * scale, b1 * scale, b2 * scale); + _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } }; diff --git a/libraries/audio/src/AudioFilterBank.cpp b/libraries/audio/src/AudioFilterBank.cpp index a2cf008fc9..a7b969540a 100644 --- a/libraries/audio/src/AudioFilterBank.cpp +++ b/libraries/audio/src/AudioFilterBank.cpp @@ -16,29 +16,33 @@ #include "AudioFilterBank.h" template<> -AudioFilterLSF1s::FilterParameter AudioFilterLSF1s::_profiles[ AudioFilterLSF1s::_profileCount ][ AudioFilterLSF1s::_filterCount ] = { +AudioFilterLSF1s::FilterParameter +AudioFilterLSF1s::_profiles[ AudioFilterLSF1s::_profileCount ][ AudioFilterLSF1s::_filterCount ] = { // Freq Gain Slope { { 1000.0f, 1.0f, 1.0f } } // flat response (default) }; template<> -AudioFilterHSF1s::FilterParameter AudioFilterHSF1s::_profiles[ AudioFilterHSF1s::_profileCount ][ AudioFilterHSF1s::_filterCount ] = { +AudioFilterHSF1s::FilterParameter +AudioFilterHSF1s::_profiles[ AudioFilterHSF1s::_profileCount ][ AudioFilterHSF1s::_filterCount ] = { // Freq Gain Slope { { 1000.0f, 1.0f, 1.0f } } // flat response (default) }; template<> -AudioFilterPEQ1s::FilterParameter AudioFilterPEQ1s::_profiles[ AudioFilterPEQ1s::_profileCount ][ AudioFilterPEQ1s::_filterCount ] = { +AudioFilterPEQ1s::FilterParameter +AudioFilterPEQ1s::_profiles[ AudioFilterPEQ1s::_profileCount ][ AudioFilterPEQ1s::_filterCount ] = { // Freq Gain Q { { 1000.0f, 1.0f, 1.0f } } // flat response (default) }; template<> -AudioFilterPEQ3m::FilterParameter AudioFilterPEQ3m::_profiles[ AudioFilterPEQ3m::_profileCount ][ AudioFilterPEQ3m::_filterCount ] = { +AudioFilterPEQ3m::FilterParameter +AudioFilterPEQ3m::_profiles[ AudioFilterPEQ3m::_profileCount ][ AudioFilterPEQ3m::_filterCount ] = { // Freq Gain Q Freq Gain Q Freq Gain Q - { { 300.0f, 1.0f, 1.0f }, { 1000.0f, 1.0f, 1.0f }, { 4000.0f, 1.0f, 1.0f } }, // flat response (default) - { { 300.0f, 1.0f, 1.0f }, { 1000.0f, 1.0f, 1.0f }, { 4000.0f, 0.1f, 1.0f } }, // treble cut - { { 300.0f, 0.1f, 1.0f }, { 1000.0f, 1.0f, 1.0f }, { 4000.0f, 1.0f, 1.0f } }, // bass cut - { { 300.0f, 1.5f, 0.71f }, { 1000.0f, 0.5f, 1.0f }, { 4000.0f, 1.50f, 0.71f } } // smiley curve + { { 300.0f, 1.0f, 1.0f }, { 1000.0f, 1.0f, 1.0f }, { 4000.0f, 1.0f, 1.0f } }, // flat response (default) + { { 300.0f, 1.0f, 1.0f }, { 1000.0f, 1.0f, 1.0f }, { 4000.0f, 0.1f, 1.0f } }, // treble cut + { { 300.0f, 0.1f, 1.0f }, { 1000.0f, 1.0f, 1.0f }, { 4000.0f, 1.0f, 1.0f } }, // bass cut + { { 300.0f, 1.5f, 0.71f }, { 1000.0f, 0.5f, 1.0f }, { 4000.0f, 1.50f, 0.71f } } // smiley curve }; diff --git a/libraries/audio/src/PositionalAudioStream.cpp b/libraries/audio/src/PositionalAudioStream.cpp index 46e83806bc..ee592a344e 100644 --- a/libraries/audio/src/PositionalAudioStream.cpp +++ b/libraries/audio/src/PositionalAudioStream.cpp @@ -33,7 +33,8 @@ PositionalAudioStream::PositionalAudioStream(PositionalAudioStream::Type type, b _lastPopOutputTrailingLoudness(0.0f), _listenerUnattenuatedZone(NULL) { - // constant defined in AudioMixer.h. However, we don't want to include this here, since we will soon find a better common home for these audio-related constants + // constant defined in AudioMixer.h. However, we don't want to include this here + // we will soon find a better common home for these audio-related constants const int SAMPLE_PHASE_DELAY_AT_90 = 20; _filter.initialize(SAMPLE_RATE, (NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (SAMPLE_PHASE_DELAY_AT_90 * 2)) / 2); } diff --git a/libraries/audio/src/PositionalAudioStream.h b/libraries/audio/src/PositionalAudioStream.h index e31cd35ad4..13cdd6b736 100644 --- a/libraries/audio/src/PositionalAudioStream.h +++ b/libraries/audio/src/PositionalAudioStream.h @@ -46,7 +46,7 @@ public: void setListenerUnattenuatedZone(AABox* listenerUnattenuatedZone) { _listenerUnattenuatedZone = listenerUnattenuatedZone; } - AudioFilterPEQ1s& getFilter() { return _filter; } + AudioFilterHSF1s& getFilter() { return _filter; } protected: // disallow copying of PositionalAudioStream objects @@ -66,7 +66,7 @@ protected: float _lastPopOutputTrailingLoudness; AABox* _listenerUnattenuatedZone; - AudioFilterPEQ1s _filter; + AudioFilterHSF1s _filter; }; #endif // hifi_PositionalAudioStream_h diff --git a/libraries/avatars/src/Referential.cpp b/libraries/avatars/src/Referential.cpp index 784ad3963c..a37aaae1b8 100644 --- a/libraries/avatars/src/Referential.cpp +++ b/libraries/avatars/src/Referential.cpp @@ -107,7 +107,7 @@ int Referential::packExtraData(unsigned char *destinationBuffer) const { int Referential::unpackExtraData(const unsigned char* sourceBuffer, int size) { _extraDataBuffer.clear(); - _extraDataBuffer.setRawData(reinterpret_cast(sourceBuffer), size); + _extraDataBuffer.append(reinterpret_cast(sourceBuffer), size); return size; }