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

Commit 80e48648 authored by Steve Kondik's avatar Steve Kondik Committed by Gerrit Code Review
Browse files

Merge "Do headset filter in center+side audio space" into gingerbread

parents 6894c153 fc2a0629
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ LOCAL_SRC_FILES := \
	EffectCompression.cpp \
	EffectEqualizer.cpp \
	EffectVirtualizer.cpp \
	FIR16.cpp \
# terminator

LOCAL_C_INCLUDES += \
+39 −27
Original line number Diff line number Diff line
@@ -38,6 +38,27 @@ EffectVirtualizer::EffectVirtualizer()
int32_t EffectVirtualizer::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize, void* pReplyData)
{
    if (cmdCode == EFFECT_CMD_CONFIGURE) {
	/* Preliminary design -- needs more work.
	 * NOT ACTUALLY USED. */
	float fir44100[16] = {
		0.584375000000000,
		0.080172281918782,
		0.049463834764832,
		-0.015690873571518,
		-0.065625000000000,
		-0.045552813136128,
		0.031786165235168,
		0.106071404788864,
		0.134375000000000,
		0.106071404788864,
		0.031786165235168,
		-0.045552813136128,
		-0.065625000000000,
		-0.015690873571518,
		0.049463834764832,
		0.080172281918782
	};

	int32_t ret = Effect::configure(pCmdData);
	if (ret != 0) {
	    int32_t *replyData = (int32_t *) pReplyData;
@@ -45,13 +66,13 @@ int32_t EffectVirtualizer::command(uint32_t cmdCode, uint32_t cmdSize, void* pCm
	    return 0;
	}

	mReverbDelayL.setParameters(mSamplingRate, 0.030f);
	mReverbDelayR.setParameters(mSamplingRate, 0.030f);
	/* Haas effect delay */
	mReverbDelayL.setParameters(mSamplingRate, 0.025f);
	mReverbDelayR.setParameters(mSamplingRate, 0.025f);
	/* Center channel forward direction adjustment filter. */
	mColorization.setParameters(fir44100);
	/* the -3 dB point is around 650 Hz, giving about 300 us to work with */
	mLocalizationL.setHighShelf(800.0f, mSamplingRate, -11.0f, 0.72f);
	mLocalizationR.setHighShelf(800.0f, mSamplingRate, -11.0f, 0.72f);
	/* Rockbox has a 0.3 ms delay line (13 samples at 44100 Hz), but
	 * I think it makes the whole effect sound pretty bad so I skipped it! */
	mLocalization.setHighShelf(800.0f, mSamplingRate, -11.0f, 0.72f);

	mDelayDataL = 0;
	mDelayDataR = 0;
@@ -152,28 +173,19 @@ int32_t EffectVirtualizer::process(audio_buffer_t* in, audio_buffer_t* out)
        dataL += dryL;
        dataR += dryR;

        /* In matrix decoding, center channel is mixed at 0.7 and the main channel at 1.
         * It follows that the sum of them is 1.7, and the proportion of the main channel
         * must be 1 / 1.7, or about 6/10. Assuming it is so, 4/10 is the contribution
         * of center, and when 2 channels are combined, the scaler is 2/10 or 1/5.
         *
         * We could try to dynamically adjust this divisor based on cross-correlation
         * between left/right channels, which would allow us to recover a reasonable
         * estimate of the music's original center channel. */
        int32_t center = (dataL + dataR) / 5;
        int32_t directL = (dataL - center);
        int32_t directR = (dataR - center);

        /* We assume center channel reaches both ears with no coloration required.
         * We could also handle it differently at reverb stage... */

        /* Apply localization filter. */
        int32_t localizedL = mLocalizationL.process(directL);
        int32_t localizedR = mLocalizationR.process(directR);
        
        /* Mix difference between channels. dataX = directX + center. */
        write(out, i * 2, dataL + localizedR);
        write(out, i * 2 + 1, dataR + localizedL);
	/* Center channel. */
	int32_t center  = (dataL + dataR) >> 1;
	/* Direct radiation components. */
	int32_t side = (dataL - dataR) >> 1;

	/* Adjust derived center channel coloration to emphasize forward
	 * direction impression. (XXX: disabled until configurable). */
	//center = mColorization.process(center);
	/* Sound reaching ear from the opposite speaker */
	side -= mLocalization.process(side);
        
        write(out, i * 2, center + side);
        write(out, i * 2 + 1, center - side);
    }

    return mEnable ? 0 : -ENODATA;
+3 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include "Biquad.h"
#include "Delay.h"
#include "Effect.h"
#include "FIR16.h"

class EffectVirtualizer : public Effect {
    private:
@@ -15,7 +16,8 @@ class EffectVirtualizer : public Effect {

    Delay mReverbDelayL, mReverbDelayR;
    int64_t mDelayDataL, mDelayDataR;
    Biquad mLocalizationL, mLocalizationR;
    FIR16 mColorization;
    Biquad mLocalization;

    void refreshStrength();

+50 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "FIR16.h"

#include <string.h>

FIR16::FIR16()
    : mIndex(0)
{
    memset(mState, 0, sizeof(mState));
    memset(mCoeff, 0, sizeof(mCoeff));
}

FIR16::~FIR16()
{
}

void FIR16::setParameters(float coeff[16])
{
    for (int32_t i = 0; i < 16; i ++) {
   	mCoeff[i] = int64_t(coeff[i] * (int64_t(1) << 32));
    }
}

int32_t FIR16::process(int32_t x0)
{
    mIndex --;
    mState[mIndex & 0xf] = x0;

    int64_t y = 0;
    for (int32_t i = 0; i < 16; i ++) {
	y += mCoeff[i] * mState[(i + mIndex) & 0xf];
    }

    return int32_t(y >> 32);
}
+15 −0
Original line number Diff line number Diff line
#pragma once

#include <stdint.h>

class FIR16 {
    int64_t mCoeff[16];
    int32_t mState[16];
    int32_t mIndex;

    public:
    FIR16();
    ~FIR16();
    void setParameters(float coeff[16]);
    int32_t process(int32_t x0);
};