Merge changes I835ec033,I11aa8f88
* changes:
AudioResampler: Add downsampling filter response test
AudioResampler: Minor test code fixes
diff --git a/media/libaudioprocessing/AudioResamplerDyn.cpp b/media/libaudioprocessing/AudioResamplerDyn.cpp
index eeeecce..52936cc 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.cpp
+++ b/media/libaudioprocessing/AudioResamplerDyn.cpp
@@ -243,7 +243,7 @@
{
// compute the normalized transition bandwidth
const double tbw = firKaiserTbw(c.mHalfNumCoefs, stopBandAtten);
- const double halfbw = tbw / 2.;
+ const double halfbw = tbw * 0.5;
double fcr; // compute fcr, the 3 dB amplitude cut-off.
if (inSampleRate < outSampleRate) { // upsample
@@ -290,7 +290,7 @@
#if 0
// Keep this debug code in case an app causes resampler design issues.
- const double halfbw = tbw / 2.;
+ const double halfbw = tbw * 0.5;
// print basic filter stats
ALOGD("L:%d hnc:%d stopBandAtten:%lf fcr:%lf atten:%lf tbw:%lf\n",
c.mL, c.mHalfNumCoefs, stopBandAtten, fcr, attenuation, tbw);
@@ -305,7 +305,7 @@
const int32_t passSteps = 1000;
- testFir(coefs, c.mL, c.mHalfNumCoefs, fp, fs, passSteps, passSteps * c.ML /*stopSteps*/,
+ testFir(coefs, c.mL, c.mHalfNumCoefs, fp, fs, passSteps, passSteps * c.mL /*stopSteps*/,
passMin, passMax, passRipple, stopMax, stopRipple);
ALOGD("passband(%lf, %lf): %.8lf %.8lf %.8lf\n", 0., fp, passMin, passMax, passRipple);
ALOGD("stopband(%lf, %lf): %.8lf %.3lf\n", fs, 0.5, stopMax, stopRipple);
diff --git a/media/libaudioprocessing/AudioResamplerFirGen.h b/media/libaudioprocessing/AudioResamplerFirGen.h
index 39cafeb..100baa3 100644
--- a/media/libaudioprocessing/AudioResamplerFirGen.h
+++ b/media/libaudioprocessing/AudioResamplerFirGen.h
@@ -547,8 +547,8 @@
wstart += wstep;
}
// renormalize - this is needed for integer filter types, use 1 for float or double.
- constexpr int64_t integralShift = std::is_integral<T>::value ? (sizeof(T) * 8 - 1) : 0;
- const double norm = 1. / (L << integralShift);
+ constexpr int integralShift = std::is_integral<T>::value ? (sizeof(T) * CHAR_BIT - 1) : 0;
+ const double norm = 1. / (int64_t{L} << integralShift);
firMin = fmin * norm;
firMax = fmax * norm;
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
index 0c8e5bb..d990111 100644
--- a/media/libaudioprocessing/tests/Android.bp
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -5,8 +5,8 @@
header_libs: ["libbase_headers"],
shared_libs: [
- "libaudioutils",
"libaudioprocessing",
+ "libaudioutils",
"libcutils",
"liblog",
"libutils",
diff --git a/media/libaudioprocessing/tests/resampler_tests.cpp b/media/libaudioprocessing/tests/resampler_tests.cpp
index e1623f7..8292291 100644
--- a/media/libaudioprocessing/tests/resampler_tests.cpp
+++ b/media/libaudioprocessing/tests/resampler_tests.cpp
@@ -246,7 +246,8 @@
}
void testFilterResponse(
- size_t channels, unsigned inputFreq, unsigned outputFreq)
+ size_t channels, unsigned inputFreq, unsigned outputFreq,
+ android::AudioResampler::src_quality quality = android::AudioResampler::DYN_HIGH_QUALITY)
{
// create resampler
using ResamplerType = android::AudioResamplerDyn<float, float, float>;
@@ -256,7 +257,7 @@
AUDIO_FORMAT_PCM_FLOAT,
channels,
outputFreq,
- android::AudioResampler::DYN_HIGH_QUALITY)));
+ quality)));
rdyn->setSampleRate(inputFreq);
// get design parameters
@@ -268,17 +269,20 @@
const double attenuation = rdyn->getFilterAttenuation();
const double stopbandDb = rdyn->getStopbandAttenuationDb();
const double passbandDb = rdyn->getPassbandRippleDb();
- const double fp = fcr - tbw / 2;
- const double fs = fcr + tbw / 2;
+ const double fp = fcr - tbw * 0.5;
+ const double fs = fcr + tbw * 0.5;
+ const double idealfs = inputFreq <= outputFreq
+ ? 0.5 // upsample
+ : 0.5 * outputFreq / inputFreq; // downsample
- printf("inputFreq:%d outputFreq:%d design"
+ printf("inputFreq:%d outputFreq:%d design quality %d"
" phases:%d halfLength:%d"
- " fcr:%lf fp:%lf fs:%lf tbw:%lf"
+ " fcr:%lf fp:%lf fs:%lf tbw:%lf fcrp:%lf"
" attenuation:%lf stopRipple:%.lf passRipple:%lf"
"\n",
- inputFreq, outputFreq,
+ inputFreq, outputFreq, quality,
phases, halfLength,
- fcr, fp, fs, tbw,
+ fcr, fp, fs, tbw, fcr * 100. / idealfs,
attenuation, stopbandDb, passbandDb);
// verify design parameters
@@ -541,8 +545,36 @@
}
}
-TEST(audioflinger_resampler, filterresponse) {
- std::vector<int> inSampleRates{
+// Selected downsampling responses for various frequencies relating to hearing aid.
+TEST(audioflinger_resampler, downsamplingresponse) {
+ static constexpr android::AudioResampler::src_quality qualities[] = {
+ android::AudioResampler::DYN_LOW_QUALITY,
+ android::AudioResampler::DYN_MED_QUALITY,
+ android::AudioResampler::DYN_HIGH_QUALITY,
+ };
+ static constexpr int inSampleRates[] = {
+ 32000,
+ 44100,
+ 48000,
+ };
+ static constexpr int outSampleRates[] = {
+ 16000,
+ 24000,
+ };
+
+ for (auto quality : qualities) {
+ for (int outSampleRate : outSampleRates) {
+ for (int inSampleRate : inSampleRates) {
+ testFilterResponse(2 /* channels */, inSampleRate, outSampleRate, quality);
+ }
+ }
+ }
+}
+
+// General responses for typical output device scenarios - 44.1, 48, 96 kHz
+// (48, 96 are part of the same resampler generation family).
+TEST(audioflinger_resampler, generalresponse) {
+ static constexpr int inSampleRates[] = {
8000,
11025,
12000,
@@ -557,7 +589,8 @@
176400,
192000,
};
- std::vector<int> outSampleRates{
+ static constexpr int outSampleRates[] = {
+ 44100,
48000,
96000,
};