summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti S. Lankila <alankila@gmail.com>2010-08-11 23:46:34 +0300
committerAntti S. Lankila <alankila@gmail.com>2010-08-18 23:32:45 +0300
commite49f58119e07e3107e5515f07522dd3b71b758a3 (patch)
tree389a9df10e9d4f414cb4c6dc6d28639b75f90f1c
parent2246292e68a8e17e550d3ddfee16354e6238685e (diff)
downloadframeworks_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.
-rw-r--r--libs/audioflinger/AudioDSP.cpp54
-rw-r--r--libs/audioflinger/AudioDSP.h2
-rw-r--r--libs/audioflinger/AudioMixer.cpp12
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;
}