diff options
author | Antti S. Lankila <alankila@gmail.com> | 2010-08-11 23:46:34 +0300 |
---|---|---|
committer | Antti S. Lankila <alankila@gmail.com> | 2010-08-18 23:32:45 +0300 |
commit | e49f58119e07e3107e5515f07522dd3b71b758a3 (patch) | |
tree | 389a9df10e9d4f414cb4c6dc6d28639b75f90f1c /libs | |
parent | 2246292e68a8e17e550d3ddfee16354e6238685e (diff) | |
download | frameworks_base-e49f58119e07e3107e5515f07522dd3b71b758a3.zip frameworks_base-e49f58119e07e3107e5515f07522dd3b71b758a3.tar.gz frameworks_base-e49f58119e07e3107e5515f07522dd3b71b758a3.tar.bz2 |
Various DSP enhancements
- Update headset to a 2nd order shelf filter, drop allpass delays
A single shelf filter can give a time delay for low frequencies
and attenuation for high frequencies yielding a headphone virtualization
directly.
- Make equalizer out of high shelves.
Cascading 4 high shelves and one global gain gives me 5 controllable bands
with passthrough characteristics when not used.
- Set loudness target to 93 %
Also correcting a volume-ramping bug which sometimes caused a slow
adjustment to desired volume because of integer truncation and invalid
round down/up algorithm. This should eliminate cases where song starts
super loud.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/audioflinger/AudioDSP.cpp | 54 | ||||
-rw-r--r-- | libs/audioflinger/AudioDSP.h | 2 | ||||
-rw-r--r-- | libs/audioflinger/AudioMixer.cpp | 12 |
3 files changed, 29 insertions, 39 deletions
diff --git a/libs/audioflinger/AudioDSP.cpp b/libs/audioflinger/AudioDSP.cpp index ae1857eb..b1c1719 100644 --- a/libs/audioflinger/AudioDSP.cpp +++ b/libs/audioflinger/AudioDSP.cpp @@ -329,9 +329,6 @@ float EffectCompression::estimateLevel(const int16_t* audioData, int32_t frames, EffectTone::EffectTone() { for (int32_t i = 0; i < 5; i ++) { - mBand[i] = 0; - } - for (int32_t i = 0; i < 5; i ++) { setBand(i, 0); } } @@ -345,6 +342,9 @@ EffectTone::~EffectTone() { void EffectTone::configure(const float samplingFrequency) { Effect::configure(samplingFrequency); + for (int i = 0; i < 5; i ++) { + mBand[i] = 0; + } refreshBands(); } @@ -354,41 +354,30 @@ void EffectTone::setBand(int32_t band, float dB) refreshBands(); } -void EffectTone::refreshBands() { +void EffectTone::refreshBands() +{ mGain = toFixedPoint(powf(10, mBand[0] / 20)); + for (int band = 0; band < 4; band ++) { + float centerFrequency = 62.5f * powf(4, band); + float dB = mBand[band+1] - mBand[band]; - for (int32_t band = 0; band < 3; band ++) { - float dB = mBand[band + 1] - mBand[0]; - float centerFrequency = 250.0f * powf(4, band); - - mFilterL[band].setPeakingEqualizer(centerFrequency, mSamplingFrequency, dB, 3.0f); - mFilterR[band].setPeakingEqualizer(centerFrequency, mSamplingFrequency, dB, 3.0f); - } - - { - int32_t band = 3; - - float dB = mBand[band + 1] - mBand[0]; - float centerFrequency = 250.0f * powf(4, band); - - mFilterL[band].setHighShelf(centerFrequency * 0.5f, mSamplingFrequency, dB, 1.0f); - mFilterR[band].setHighShelf(centerFrequency * 0.5f, mSamplingFrequency, dB, 1.0f); + mFilterL[band].setHighShelf(centerFrequency * 2.0f, mSamplingFrequency, dB, 1.0f); + mFilterR[band].setHighShelf(centerFrequency * 2.0f, mSamplingFrequency, dB, 1.0f); } } void EffectTone::process(int32_t* inout, int32_t frames) { for (int32_t i = 0; i < frames; i ++) { - int32_t tmpL = inout[0] >> fixedPointDecimals; - int32_t tmpR = inout[1] >> fixedPointDecimals; - /* 16 bits */ - - /* bass control is really a global gain compensated by other - * controls */ - tmpL = tmpL * mGain; - tmpR = tmpR * mGain; + int32_t tmpL = inout[0]; + int32_t tmpR = inout[1]; /* 28 bits */ - + + /* first "shelve" is just gain */ + tmpL = (tmpL >> fixedPointDecimals) * mGain; + tmpR = (tmpR >> fixedPointDecimals) * mGain; + /* 28 bits */ + /* evaluate the other filters. * I'm ignoring the integer truncation problem here, but in reality * it should be accounted for. */ @@ -424,10 +413,9 @@ void EffectHeadphone::configure(const float samplingFrequency) { mReverbDelayL.setParameters(mSamplingFrequency, 0.030f); mReverbDelayR.setParameters(mSamplingFrequency, 0.030f); - /* the -3 dB point is around 700 Hz, similar to the classic design - * in bs2b. */ - mLowpassL.setHighShelf1(1500.0f, mSamplingFrequency, -16.0f); - mLowpassR.setHighShelf1(1500.0f, mSamplingFrequency, -16.0f); + /* the -3 dB point is around 650 Hz, giving about 300 us to work with */ + mLowpassL.setHighShelf(800.0f, mSamplingFrequency, -12.0f, 0.72f); + mLowpassR.setHighShelf(800.0f, mSamplingFrequency, -12.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! */ } diff --git a/libs/audioflinger/AudioDSP.h b/libs/audioflinger/AudioDSP.h index 1d77a8d..e1b0933 100644 --- a/libs/audioflinger/AudioDSP.h +++ b/libs/audioflinger/AudioDSP.h @@ -101,7 +101,7 @@ class EffectCompression : public Effect { class EffectTone : public Effect { float mBand[5]; - int32_t mGain; + int mGain; Biquad mFilterL[4], mFilterR[4]; void refreshBands(); diff --git a/libs/audioflinger/AudioMixer.cpp b/libs/audioflinger/AudioMixer.cpp index e5985d7..1853c61 100644 --- a/libs/audioflinger/AudioMixer.cpp +++ b/libs/audioflinger/AudioMixer.cpp @@ -38,8 +38,8 @@ static inline int16_t clamp16(int32_t sample) return sample; } -static int32_t seed = 1; inline static int32_t prng() { + static int32_t seed = 1; seed = (seed * 12345) + 1103515245; return int32_t(seed & 0xfff); } @@ -59,6 +59,8 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, AudioDSP& dsp) track_t* t = mState.tracks; for (int i=0 ; i<32 ; i++) { t->needs = 0; + t->prevVolume[0] = UNITY_GAIN; + t->prevVolume[1] = UNITY_GAIN; t->volume[0] = UNITY_GAIN; t->volume[1] = UNITY_GAIN; t->volumeInc[0] = 0; @@ -255,17 +257,17 @@ void AudioMixer::track_t::adjustVolumeRamp(AudioDSP& dsp, size_t frames) int32_t d = desiredVolume - prevVolume[i]; /* limit change rate to smooth the compressor. */ - int32_t volChangeLimit = (prevVolume[i] >> 10); + int32_t volChangeLimit = (prevVolume[i] >> 9); - volChangeLimit += 1; + volChangeLimit -= 1; int32_t volInc = d / int32_t(frames); if (volInc < -(volChangeLimit)) { volInc = -(volChangeLimit); } /* Make ramps up slower, but ramps down fast. */ - volChangeLimit >>= 3; - volChangeLimit -= 1; + volChangeLimit >>= 4; + volChangeLimit += 1; if (volInc > volChangeLimit) { volInc = volChangeLimit; } |