Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a3f3aa7 authored by Steve Kondik's avatar Steve Kondik Committed by Gerrit Code Review
Browse files

Merge "Smooth biquad interpolation for equalizer" into gingerbread

parents 4cc2e9e4 61231f5c
Loading
Loading
Loading
Loading
+51 −14
Original line number Diff line number Diff line
@@ -24,34 +24,56 @@ static int64_t toFixedPoint(float in) {
Biquad::Biquad()
{
    reset();
    setCoefficients(1, 0, 0, 0, 0, 0);
    setCoefficients(0, 1, 0, 0, 1, 0, 0);
}

Biquad::~Biquad()
{
}

void Biquad::setCoefficients(float a0, float a1, float a2, float b0, float b1, float b2)
void Biquad::setCoefficients(int32_t steps, float a0, float a1, float a2, float b0, float b1, float b2)
{
    mA1 = -toFixedPoint(a1/a0);
    mA2 = -toFixedPoint(a2/a0);
    mB0 = toFixedPoint(b0/a0);
    mB1 = toFixedPoint(b1/a0);
    mB2 = toFixedPoint(b2/a0);
    int64_t A1 = -toFixedPoint(a1/a0);
    int64_t A2 = -toFixedPoint(a2/a0);
    int64_t B0 = toFixedPoint(b0/a0);
    int64_t B1 = toFixedPoint(b1/a0);
    int64_t B2 = toFixedPoint(b2/a0);

    if (steps == 0) {
	mA1 = A1;
	mA2 = A2;
	mB0 = B0;
	mB1 = B1;
	mB2 = B2;
	mInterpolationSteps = 0;
    } else {
	mA1dif = (A1 - mA1) / steps;
	mA2dif = (A2 - mA2) / steps;
	mB0dif = (B0 - mB0) / steps;
	mB1dif = (B1 - mB1) / steps;
	mB2dif = (B2 - mB2) / steps;
	mInterpolationSteps = steps;
    }
}

void Biquad::reset()
{
    mInterpolationSteps = 0;
    mA1 = 0;
    mA2 = 0;
    mB0 = 0;
    mB1 = 0;
    mB2 = 0;
    mX1 = 0;
    mX2 = 0;
    mY1 = 0;
    mY2 = 0;
}

void Biquad::setHighShelf(float center_frequency, float sampling_frequency, float db_gain, float slope)
void Biquad::setHighShelf(int32_t steps, float center_frequency, float sampling_frequency, float gainDb, float slope, float overallGainDb)
{
    float w0 = 2 * (float) M_PI * center_frequency / sampling_frequency;
    float A = powf(10, db_gain/40);
    float A = powf(10, gainDb/40);
    float alpha = sinf(w0)/2 * sqrtf( (A + 1/A)*(1/slope - 1) + 2 );

    float b0 =    A*( (A+1) + (A-1)*cosf(w0) + 2*sqrtf(A)*alpha );
@@ -61,10 +83,15 @@ void Biquad::setHighShelf(float center_frequency, float sampling_frequency, floa
    float a1 =    2*( (A-1) - (A+1)*cosf(w0)                   );
    float a2 =        (A+1) - (A-1)*cosf(w0) - 2*sqrtf(A)*alpha  ;

    setCoefficients(a0, a1, a2, b0, b1, b2);
    float overallGain = powf(10, overallGainDb / 20);
    b0 *= overallGain;
    b1 *= overallGain;
    b2 *= overallGain;

    setCoefficients(steps, a0, a1, a2, b0, b1, b2);
}

void Biquad::setBandPass(float center_frequency, float sampling_frequency, float resonance)
void Biquad::setBandPass(int32_t steps, float center_frequency, float sampling_frequency, float resonance)
{
    float w0 = 2 * (float) M_PI * center_frequency / sampling_frequency;
    float alpha = sinf(w0) / (2*resonance);
@@ -76,10 +103,10 @@ void Biquad::setBandPass(float center_frequency, float sampling_frequency, float
    float a1 =  -2*cosf(w0);
    float a2 =   1 - alpha;

    setCoefficients(a0, a1, a2, b0, b1, b2);
    setCoefficients(steps, a0, a1, a2, b0, b1, b2);
}

void Biquad::setLowPass(float center_frequency, float sampling_frequency, float resonance)
void Biquad::setLowPass(int32_t steps, float center_frequency, float sampling_frequency, float resonance)
{
    float w0 = 2 * (float) M_PI * center_frequency / sampling_frequency;
    float alpha = sinf(w0) / (2*resonance);
@@ -91,7 +118,7 @@ void Biquad::setLowPass(float center_frequency, float sampling_frequency, float
    float a1 =  -2*cosf(w0);
    float a2 =   1 - alpha;

    setCoefficients(a0, a1, a2, b0, b1, b2);
    setCoefficients(steps, a0, a1, a2, b0, b1, b2);
}

int32_t Biquad::process(int32_t x0)
@@ -109,5 +136,15 @@ int32_t Biquad::process(int32_t x0)
    mX2 = mX1;
    mX1 = x0;

    /* Interpolate biquad parameters */
    if (mInterpolationSteps != 0) {
	mInterpolationSteps --;
	mB0 += mB0dif;
	mB1 += mB1dif;
	mB2 += mB2dif;
	mA1 += mA1dif;
	mA2 += mA2dif;
    }

    return y0;
}
+6 −4
Original line number Diff line number Diff line
@@ -7,15 +7,17 @@ class Biquad {
    int32_t mX1, mX2;
    int32_t mY1, mY2;
    int64_t mB0, mB1, mB2, mA1, mA2;
    int64_t mB0dif, mB1dif, mB2dif, mA1dif, mA2dif;
    int32_t mInterpolationSteps;

    void setCoefficients(float a0, float a1, float a2, float b0, float b1, float b2);
    void setCoefficients(int32_t steps, float a0, float a1, float a2, float b0, float b1, float b2);

    public:
    Biquad();
    virtual ~Biquad();
    void setHighShelf(float cf, float sf, float gain, float slope);
    void setBandPass(float cf, float sf, float resonance);
    void setLowPass(float cf, float sf, float resonance);
    void setHighShelf(int32_t steps, float cf, float sf, float gaindB, float slope, float overallGain);
    void setBandPass(int32_t steps, float cf, float sf, float resonance);
    void setLowPass(int32_t steps, float cf, float sf, float resonance);
    int32_t process(int32_t in);
    void reset();
};
+1 −1
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ int32_t EffectBassBoost::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdD
void EffectBassBoost::refreshStrength()
{
    /* Q = 0.5 .. 2.0 */
    mBoost.setLowPass(55.0f, mSamplingRate, 0.5f + mStrength / 666.0f);
    mBoost.setLowPass(0, 55.0f, mSamplingRate, 0.5f + mStrength / 666.0f);
}

int32_t EffectBassBoost::process(audio_buffer_t* in, audio_buffer_t* out)
+2 −2
Original line number Diff line number Diff line
@@ -53,8 +53,8 @@ int32_t EffectCompression::command(uint32_t cmdCode, uint32_t cmdSize, void* pCm

        /* This filter gives a reasonable approximation of A- and C-weighting
         * which is close to correct for 100 - 10 kHz. 10 dB gain must be added to result. */
	mWeigherBP[0].setBandPass(2200, mSamplingRate, 0.33);
	mWeigherBP[1].setBandPass(2200, mSamplingRate, 0.33);
	mWeigherBP[0].setBandPass(0, 2200, mSamplingRate, 0.33);
	mWeigherBP[1].setBandPass(0, 2200, mSamplingRate, 0.33);

	*replyData = 0;
	return 0;
+4 −7
Original line number Diff line number Diff line
@@ -230,14 +230,15 @@ float EffectEqualizer::getAdjustedBand(int32_t band) {

void EffectEqualizer::refreshBands()
{
    mGain = toFixedPoint(powf(10.0f, getAdjustedBand(0) / 20.0f));
    for (int32_t band = 0; band < 5; band ++) {
	/* 15.625, 62.5, 250, 1000, 4000, 16000 */
        float centerFrequency = 15.625f * powf(4, band);
        float dB = getAdjustedBand(band + 1) - getAdjustedBand(band);

        mFilterL[band].setHighShelf(centerFrequency * 2.0f, mSamplingRate, dB, 1.0f);
        mFilterR[band].setHighShelf(centerFrequency * 2.0f, mSamplingRate, dB, 1.0f);
	float overallGain = band == 0 ? getAdjustedBand(0) : 0.0f;

        mFilterL[band].setHighShelf(mNextUpdateInterval, centerFrequency * 2.0f, mSamplingRate, dB, 1.0f, overallGain);
        mFilterR[band].setHighShelf(mNextUpdateInterval, centerFrequency * 2.0f, mSamplingRate, dB, 1.0f, overallGain);
    }
}

@@ -283,10 +284,6 @@ int32_t EffectEqualizer::process(audio_buffer_t *in, audio_buffer_t *out)
        int64_t weight = tmpL + tmpR;
        mPowerSquared += weight * weight;
     
        /* first "shelve" is just gain */ 
        tmpL = tmpL * mGain >> 32;
        tmpR = tmpR * mGain >> 32;
 
        /* evaluate the other filters. */
        for (int32_t j = 0; j < 5; j ++) {
            tmpL = mFilterL[j].process(tmpL);
Loading