blob: a23c00010932dc1d6df01e3588b7a3e28d704942 [file] [log] [blame]
Andy Hung546734b2014-04-01 18:31:42 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "audioflinger_resampler_tests"
19
Mark Salyzyn60d02072016-09-29 08:48:48 -070020#include <errno.h>
21#include <fcntl.h>
22#include <math.h>
Andy Hung546734b2014-04-01 18:31:42 -070023#include <stdio.h>
24#include <stdlib.h>
Andy Hung546734b2014-04-01 18:31:42 -070025#include <string.h>
26#include <sys/mman.h>
27#include <sys/stat.h>
Andy Hung546734b2014-04-01 18:31:42 -070028#include <time.h>
Mark Salyzyn60d02072016-09-29 08:48:48 -070029#include <unistd.h>
30
Andy Hung42b01112014-07-20 14:04:19 -070031#include <iostream>
Mark Salyzyn60d02072016-09-29 08:48:48 -070032#include <utility>
33#include <vector>
34
Andy Hung546734b2014-04-01 18:31:42 -070035#include <gtest/gtest.h>
Mark Salyzyne74bbf12017-01-12 15:10:27 -080036#include <log/log.h>
Andy Hung546734b2014-04-01 18:31:42 -070037#include <media/AudioBufferProvider.h>
Mark Salyzyn60d02072016-09-29 08:48:48 -070038
Andy Hung068561c2017-01-03 17:09:32 -080039#include <media/AudioResampler.h>
Andy Hungc0e5ec82014-06-17 14:33:39 -070040#include "test_utils.h"
Andy Hung546734b2014-04-01 18:31:42 -070041
Andy Hungadc5d9c2017-01-05 17:26:08 -080042template <typename T>
43static void printData(T *data, size_t size) {
44 const size_t stride = 8;
45 for (size_t i = 0; i < size; ) {
46 for (size_t j = 0; j < stride && i < size; ++j) {
47 std::cout << data[i++] << ' '; // extra space before newline
48 }
49 std::cout << '\n'; // or endl
50 }
51}
52
Andy Hung075abae2014-04-09 19:36:43 -070053void resample(int channels, void *output,
54 size_t outputFrames, const std::vector<size_t> &outputIncr,
Andy Hung546734b2014-04-01 18:31:42 -070055 android::AudioBufferProvider *provider, android::AudioResampler *resampler)
56{
57 for (size_t i = 0, j = 0; i < outputFrames; ) {
58 size_t thisFrames = outputIncr[j++];
59 if (j >= outputIncr.size()) {
60 j = 0;
61 }
62 if (thisFrames == 0 || thisFrames > outputFrames - i) {
63 thisFrames = outputFrames - i;
64 }
Andy Hung6b3b7e32015-03-29 00:49:22 -070065 size_t framesResampled = resampler->resample(
66 (int32_t*) output + channels*i, thisFrames, provider);
67 // we should have enough buffer space, so there is no short count.
68 ASSERT_EQ(thisFrames, framesResampled);
Andy Hung546734b2014-04-01 18:31:42 -070069 i += thisFrames;
70 }
71}
72
73void buffercmp(const void *reference, const void *test,
74 size_t outputFrameSize, size_t outputFrames)
75{
76 for (size_t i = 0; i < outputFrames; ++i) {
77 int check = memcmp((const char*)reference + i * outputFrameSize,
78 (const char*)test + i * outputFrameSize, outputFrameSize);
79 if (check) {
Glenn Kastena4daf0b2014-07-28 16:34:45 -070080 ALOGE("Failure at frame %zu", i);
Andy Hung546734b2014-04-01 18:31:42 -070081 ASSERT_EQ(check, 0); /* fails */
82 }
83 }
84}
85
Andy Hung075abae2014-04-09 19:36:43 -070086void testBufferIncrement(size_t channels, bool useFloat,
87 unsigned inputFreq, unsigned outputFreq,
Andy Hung546734b2014-04-01 18:31:42 -070088 enum android::AudioResampler::src_quality quality)
89{
Andy Hung3348e362014-07-07 10:21:44 -070090 const audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
Andy Hung546734b2014-04-01 18:31:42 -070091 // create the provider
Andy Hungc0e5ec82014-06-17 14:33:39 -070092 std::vector<int> inputIncr;
93 SignalProvider provider;
Andy Hung075abae2014-04-09 19:36:43 -070094 if (useFloat) {
95 provider.setChirp<float>(channels,
96 0., outputFreq/2., outputFreq, outputFreq/2000.);
97 } else {
98 provider.setChirp<int16_t>(channels,
99 0., outputFreq/2., outputFreq, outputFreq/2000.);
100 }
Andy Hungc0e5ec82014-06-17 14:33:39 -0700101 provider.setIncr(inputIncr);
Andy Hung546734b2014-04-01 18:31:42 -0700102
103 // calculate the output size
104 size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq;
Andy Hungadc5d9c2017-01-05 17:26:08 -0800105 size_t outputFrameSize = (channels == 1 ? 2 : channels) * (useFloat ? sizeof(float) : sizeof(int32_t));
Andy Hung546734b2014-04-01 18:31:42 -0700106 size_t outputSize = outputFrameSize * outputFrames;
107 outputSize &= ~7;
108
109 // create the resampler
Andy Hung546734b2014-04-01 18:31:42 -0700110 android::AudioResampler* resampler;
111
Andy Hung3348e362014-07-07 10:21:44 -0700112 resampler = android::AudioResampler::create(format, channels, outputFreq, quality);
Andy Hung546734b2014-04-01 18:31:42 -0700113 resampler->setSampleRate(inputFreq);
Andy Hung5e58b0a2014-06-23 19:07:29 -0700114 resampler->setVolume(android::AudioResampler::UNITY_GAIN_FLOAT,
115 android::AudioResampler::UNITY_GAIN_FLOAT);
Andy Hung546734b2014-04-01 18:31:42 -0700116
117 // set up the reference run
118 std::vector<size_t> refIncr;
119 refIncr.push_back(outputFrames);
Andy Hungccbba6e2017-01-05 16:43:35 -0800120 void* reference = calloc(outputFrames, outputFrameSize);
Andy Hung075abae2014-04-09 19:36:43 -0700121 resample(channels, reference, outputFrames, refIncr, &provider, resampler);
Andy Hung546734b2014-04-01 18:31:42 -0700122
123 provider.reset();
124
125#if 0
126 /* this test will fail - API interface issue: reset() does not clear internal buffers */
127 resampler->reset();
128#else
129 delete resampler;
Andy Hung3348e362014-07-07 10:21:44 -0700130 resampler = android::AudioResampler::create(format, channels, outputFreq, quality);
Andy Hung546734b2014-04-01 18:31:42 -0700131 resampler->setSampleRate(inputFreq);
Andy Hung5e58b0a2014-06-23 19:07:29 -0700132 resampler->setVolume(android::AudioResampler::UNITY_GAIN_FLOAT,
133 android::AudioResampler::UNITY_GAIN_FLOAT);
Andy Hung546734b2014-04-01 18:31:42 -0700134#endif
135
136 // set up the test run
137 std::vector<size_t> outIncr;
138 outIncr.push_back(1);
139 outIncr.push_back(2);
140 outIncr.push_back(3);
Andy Hungccbba6e2017-01-05 16:43:35 -0800141 void* test = calloc(outputFrames, outputFrameSize);
Andy Hung075abae2014-04-09 19:36:43 -0700142 inputIncr.push_back(1);
143 inputIncr.push_back(3);
144 provider.setIncr(inputIncr);
145 resample(channels, test, outputFrames, outIncr, &provider, resampler);
Andy Hung546734b2014-04-01 18:31:42 -0700146
147 // check
148 buffercmp(reference, test, outputFrameSize, outputFrames);
149
150 free(reference);
151 free(test);
152 delete resampler;
153}
154
155template <typename T>
156inline double sqr(T v)
157{
158 double dv = static_cast<double>(v);
159 return dv * dv;
160}
161
162template <typename T>
163double signalEnergy(T *start, T *end, unsigned stride)
164{
165 double accum = 0;
166
167 for (T *p = start; p < end; p += stride) {
168 accum += sqr(*p);
169 }
170 unsigned count = (end - start + stride - 1) / stride;
171 return accum / count;
172}
173
Andy Hung42b01112014-07-20 14:04:19 -0700174// TI = resampler input type, int16_t or float
175// TO = resampler output type, int32_t or float
176template <typename TI, typename TO>
Andy Hung546734b2014-04-01 18:31:42 -0700177void testStopbandDownconversion(size_t channels,
178 unsigned inputFreq, unsigned outputFreq,
179 unsigned passband, unsigned stopband,
180 enum android::AudioResampler::src_quality quality)
181{
182 // create the provider
Andy Hungc0e5ec82014-06-17 14:33:39 -0700183 std::vector<int> inputIncr;
184 SignalProvider provider;
Andy Hung42b01112014-07-20 14:04:19 -0700185 provider.setChirp<TI>(channels,
Andy Hungc0e5ec82014-06-17 14:33:39 -0700186 0., inputFreq/2., inputFreq, inputFreq/2000.);
187 provider.setIncr(inputIncr);
Andy Hung546734b2014-04-01 18:31:42 -0700188
189 // calculate the output size
190 size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq;
Andy Hungadc5d9c2017-01-05 17:26:08 -0800191 size_t outputFrameSize = (channels == 1 ? 2 : channels) * sizeof(TO);
Andy Hung546734b2014-04-01 18:31:42 -0700192 size_t outputSize = outputFrameSize * outputFrames;
193 outputSize &= ~7;
194
195 // create the resampler
Andy Hung546734b2014-04-01 18:31:42 -0700196 android::AudioResampler* resampler;
197
Andy Hung42b01112014-07-20 14:04:19 -0700198 resampler = android::AudioResampler::create(
199 is_same<TI, int16_t>::value ? AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT,
Andy Hung3348e362014-07-07 10:21:44 -0700200 channels, outputFreq, quality);
Andy Hung546734b2014-04-01 18:31:42 -0700201 resampler->setSampleRate(inputFreq);
Andy Hung5e58b0a2014-06-23 19:07:29 -0700202 resampler->setVolume(android::AudioResampler::UNITY_GAIN_FLOAT,
203 android::AudioResampler::UNITY_GAIN_FLOAT);
Andy Hung546734b2014-04-01 18:31:42 -0700204
205 // set up the reference run
206 std::vector<size_t> refIncr;
207 refIncr.push_back(outputFrames);
Andy Hungccbba6e2017-01-05 16:43:35 -0800208 void* reference = calloc(outputFrames, outputFrameSize);
Andy Hung075abae2014-04-09 19:36:43 -0700209 resample(channels, reference, outputFrames, refIncr, &provider, resampler);
Andy Hung546734b2014-04-01 18:31:42 -0700210
Andy Hung42b01112014-07-20 14:04:19 -0700211 TO *out = reinterpret_cast<TO *>(reference);
Andy Hung546734b2014-04-01 18:31:42 -0700212
213 // check signal energy in passband
214 const unsigned passbandFrame = passband * outputFreq / 1000.;
215 const unsigned stopbandFrame = stopband * outputFreq / 1000.;
216
217 // check each channel separately
Andy Hungadc5d9c2017-01-05 17:26:08 -0800218 if (channels == 1) channels = 2; // workaround (mono duplicates output channel)
219
Andy Hung546734b2014-04-01 18:31:42 -0700220 for (size_t i = 0; i < channels; ++i) {
221 double passbandEnergy = signalEnergy(out, out + passbandFrame * channels, channels);
222 double stopbandEnergy = signalEnergy(out + stopbandFrame * channels,
223 out + outputFrames * channels, channels);
224 double dbAtten = -10. * log10(stopbandEnergy / passbandEnergy);
225 ASSERT_GT(dbAtten, 60.);
226
227#if 0
228 // internal verification
229 printf("if:%d of:%d pbf:%d sbf:%d sbe: %f pbe: %f db: %.2f\n",
230 provider.getNumFrames(), outputFrames,
231 passbandFrame, stopbandFrame, stopbandEnergy, passbandEnergy, dbAtten);
232 for (size_t i = 0; i < 10; ++i) {
Andy Hung42b01112014-07-20 14:04:19 -0700233 std::cout << out[i+passbandFrame*channels] << std::endl;
Andy Hung546734b2014-04-01 18:31:42 -0700234 }
235 for (size_t i = 0; i < 10; ++i) {
Andy Hung42b01112014-07-20 14:04:19 -0700236 std::cout << out[i+stopbandFrame*channels] << std::endl;
Andy Hung546734b2014-04-01 18:31:42 -0700237 }
238#endif
239 }
240
241 free(reference);
242 delete resampler;
243}
244
245/* Buffer increment test
246 *
247 * We compare a reference output, where we consume and process the entire
248 * buffer at a time, and a test output, where we provide small chunks of input
249 * data and process small chunks of output (which may not be equivalent in size).
250 *
251 * Two subtests - fixed phase (3:2 down) and interpolated phase (147:320 up)
252 */
253TEST(audioflinger_resampler, bufferincrement_fixedphase) {
254 // all of these work
255 static const enum android::AudioResampler::src_quality kQualityArray[] = {
256 android::AudioResampler::LOW_QUALITY,
257 android::AudioResampler::MED_QUALITY,
258 android::AudioResampler::HIGH_QUALITY,
259 android::AudioResampler::VERY_HIGH_QUALITY,
260 android::AudioResampler::DYN_LOW_QUALITY,
261 android::AudioResampler::DYN_MED_QUALITY,
262 android::AudioResampler::DYN_HIGH_QUALITY,
263 };
264
265 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
Andy Hung075abae2014-04-09 19:36:43 -0700266 testBufferIncrement(2, false, 48000, 32000, kQualityArray[i]);
Andy Hung546734b2014-04-01 18:31:42 -0700267 }
268}
269
270TEST(audioflinger_resampler, bufferincrement_interpolatedphase) {
271 // all of these work except low quality
272 static const enum android::AudioResampler::src_quality kQualityArray[] = {
273// android::AudioResampler::LOW_QUALITY,
274 android::AudioResampler::MED_QUALITY,
275 android::AudioResampler::HIGH_QUALITY,
276 android::AudioResampler::VERY_HIGH_QUALITY,
277 android::AudioResampler::DYN_LOW_QUALITY,
278 android::AudioResampler::DYN_MED_QUALITY,
279 android::AudioResampler::DYN_HIGH_QUALITY,
280 };
281
282 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
Andy Hung075abae2014-04-09 19:36:43 -0700283 testBufferIncrement(2, false, 22050, 48000, kQualityArray[i]);
284 }
285}
286
287TEST(audioflinger_resampler, bufferincrement_fixedphase_multi) {
288 // only dynamic quality
289 static const enum android::AudioResampler::src_quality kQualityArray[] = {
290 android::AudioResampler::DYN_LOW_QUALITY,
291 android::AudioResampler::DYN_MED_QUALITY,
292 android::AudioResampler::DYN_HIGH_QUALITY,
293 };
294
295 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
296 testBufferIncrement(4, false, 48000, 32000, kQualityArray[i]);
297 }
298}
299
300TEST(audioflinger_resampler, bufferincrement_interpolatedphase_multi_float) {
301 // only dynamic quality
302 static const enum android::AudioResampler::src_quality kQualityArray[] = {
303 android::AudioResampler::DYN_LOW_QUALITY,
304 android::AudioResampler::DYN_MED_QUALITY,
305 android::AudioResampler::DYN_HIGH_QUALITY,
306 };
307
308 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
309 testBufferIncrement(8, true, 22050, 48000, kQualityArray[i]);
Andy Hung546734b2014-04-01 18:31:42 -0700310 }
311}
312
313/* Simple aliasing test
314 *
315 * This checks stopband response of the chirp signal to make sure frequencies
316 * are properly suppressed. It uses downsampling because the stopband can be
317 * clearly isolated by input frequencies exceeding the output sample rate (nyquist).
318 */
Andy Hung42b01112014-07-20 14:04:19 -0700319TEST(audioflinger_resampler, stopbandresponse_integer) {
Andy Hung546734b2014-04-01 18:31:42 -0700320 // not all of these may work (old resamplers fail on downsampling)
321 static const enum android::AudioResampler::src_quality kQualityArray[] = {
322 //android::AudioResampler::LOW_QUALITY,
323 //android::AudioResampler::MED_QUALITY,
324 //android::AudioResampler::HIGH_QUALITY,
325 //android::AudioResampler::VERY_HIGH_QUALITY,
326 android::AudioResampler::DYN_LOW_QUALITY,
327 android::AudioResampler::DYN_MED_QUALITY,
328 android::AudioResampler::DYN_HIGH_QUALITY,
329 };
330
331 // in this test we assume a maximum transition band between 12kHz and 20kHz.
332 // there must be at least 60dB relative attenuation between stopband and passband.
333 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
Andy Hung42b01112014-07-20 14:04:19 -0700334 testStopbandDownconversion<int16_t, int32_t>(
335 2, 48000, 32000, 12000, 20000, kQualityArray[i]);
Andy Hung546734b2014-04-01 18:31:42 -0700336 }
337
338 // in this test we assume a maximum transition band between 7kHz and 15kHz.
339 // there must be at least 60dB relative attenuation between stopband and passband.
340 // (the weird ratio triggers interpolative resampling)
341 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
Andy Hung42b01112014-07-20 14:04:19 -0700342 testStopbandDownconversion<int16_t, int32_t>(
343 2, 48000, 22101, 7000, 15000, kQualityArray[i]);
Andy Hung546734b2014-04-01 18:31:42 -0700344 }
345}
Andy Hung42b01112014-07-20 14:04:19 -0700346
Andy Hungadc5d9c2017-01-05 17:26:08 -0800347TEST(audioflinger_resampler, stopbandresponse_integer_mono) {
348 // not all of these may work (old resamplers fail on downsampling)
349 static const enum android::AudioResampler::src_quality kQualityArray[] = {
350 //android::AudioResampler::LOW_QUALITY,
351 //android::AudioResampler::MED_QUALITY,
352 //android::AudioResampler::HIGH_QUALITY,
353 //android::AudioResampler::VERY_HIGH_QUALITY,
354 android::AudioResampler::DYN_LOW_QUALITY,
355 android::AudioResampler::DYN_MED_QUALITY,
356 android::AudioResampler::DYN_HIGH_QUALITY,
357 };
358
359 // in this test we assume a maximum transition band between 12kHz and 20kHz.
360 // there must be at least 60dB relative attenuation between stopband and passband.
361 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
362 testStopbandDownconversion<int16_t, int32_t>(
363 1, 48000, 32000, 12000, 20000, kQualityArray[i]);
364 }
365
366 // in this test we assume a maximum transition band between 7kHz and 15kHz.
367 // there must be at least 60dB relative attenuation between stopband and passband.
368 // (the weird ratio triggers interpolative resampling)
369 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
370 testStopbandDownconversion<int16_t, int32_t>(
371 1, 48000, 22101, 7000, 15000, kQualityArray[i]);
372 }
373}
374
Andy Hung42b01112014-07-20 14:04:19 -0700375TEST(audioflinger_resampler, stopbandresponse_integer_multichannel) {
376 // not all of these may work (old resamplers fail on downsampling)
377 static const enum android::AudioResampler::src_quality kQualityArray[] = {
378 //android::AudioResampler::LOW_QUALITY,
379 //android::AudioResampler::MED_QUALITY,
380 //android::AudioResampler::HIGH_QUALITY,
381 //android::AudioResampler::VERY_HIGH_QUALITY,
382 android::AudioResampler::DYN_LOW_QUALITY,
383 android::AudioResampler::DYN_MED_QUALITY,
384 android::AudioResampler::DYN_HIGH_QUALITY,
385 };
386
387 // in this test we assume a maximum transition band between 12kHz and 20kHz.
388 // there must be at least 60dB relative attenuation between stopband and passband.
389 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
390 testStopbandDownconversion<int16_t, int32_t>(
391 8, 48000, 32000, 12000, 20000, kQualityArray[i]);
392 }
393
394 // in this test we assume a maximum transition band between 7kHz and 15kHz.
395 // there must be at least 60dB relative attenuation between stopband and passband.
396 // (the weird ratio triggers interpolative resampling)
397 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
398 testStopbandDownconversion<int16_t, int32_t>(
399 8, 48000, 22101, 7000, 15000, kQualityArray[i]);
400 }
401}
402
403TEST(audioflinger_resampler, stopbandresponse_float) {
404 // not all of these may work (old resamplers fail on downsampling)
405 static const enum android::AudioResampler::src_quality kQualityArray[] = {
406 //android::AudioResampler::LOW_QUALITY,
407 //android::AudioResampler::MED_QUALITY,
408 //android::AudioResampler::HIGH_QUALITY,
409 //android::AudioResampler::VERY_HIGH_QUALITY,
410 android::AudioResampler::DYN_LOW_QUALITY,
411 android::AudioResampler::DYN_MED_QUALITY,
412 android::AudioResampler::DYN_HIGH_QUALITY,
413 };
414
415 // in this test we assume a maximum transition band between 12kHz and 20kHz.
416 // there must be at least 60dB relative attenuation between stopband and passband.
417 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
418 testStopbandDownconversion<float, float>(
419 2, 48000, 32000, 12000, 20000, kQualityArray[i]);
420 }
421
422 // in this test we assume a maximum transition band between 7kHz and 15kHz.
423 // there must be at least 60dB relative attenuation between stopband and passband.
424 // (the weird ratio triggers interpolative resampling)
425 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
426 testStopbandDownconversion<float, float>(
427 2, 48000, 22101, 7000, 15000, kQualityArray[i]);
428 }
429}
430
Andy Hungadc5d9c2017-01-05 17:26:08 -0800431TEST(audioflinger_resampler, stopbandresponse_float_mono) {
432 // not all of these may work (old resamplers fail on downsampling)
433 static const enum android::AudioResampler::src_quality kQualityArray[] = {
434 //android::AudioResampler::LOW_QUALITY,
435 //android::AudioResampler::MED_QUALITY,
436 //android::AudioResampler::HIGH_QUALITY,
437 //android::AudioResampler::VERY_HIGH_QUALITY,
438 android::AudioResampler::DYN_LOW_QUALITY,
439 android::AudioResampler::DYN_MED_QUALITY,
440 android::AudioResampler::DYN_HIGH_QUALITY,
441 };
442
443 // in this test we assume a maximum transition band between 12kHz and 20kHz.
444 // there must be at least 60dB relative attenuation between stopband and passband.
445 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
446 testStopbandDownconversion<float, float>(
447 1, 48000, 32000, 12000, 20000, kQualityArray[i]);
448 }
449
450 // in this test we assume a maximum transition band between 7kHz and 15kHz.
451 // there must be at least 60dB relative attenuation between stopband and passband.
452 // (the weird ratio triggers interpolative resampling)
453 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
454 testStopbandDownconversion<float, float>(
455 1, 48000, 22101, 7000, 15000, kQualityArray[i]);
456 }
457}
458
Andy Hung42b01112014-07-20 14:04:19 -0700459TEST(audioflinger_resampler, stopbandresponse_float_multichannel) {
460 // not all of these may work (old resamplers fail on downsampling)
461 static const enum android::AudioResampler::src_quality kQualityArray[] = {
462 //android::AudioResampler::LOW_QUALITY,
463 //android::AudioResampler::MED_QUALITY,
464 //android::AudioResampler::HIGH_QUALITY,
465 //android::AudioResampler::VERY_HIGH_QUALITY,
466 android::AudioResampler::DYN_LOW_QUALITY,
467 android::AudioResampler::DYN_MED_QUALITY,
468 android::AudioResampler::DYN_HIGH_QUALITY,
469 };
470
471 // in this test we assume a maximum transition band between 12kHz and 20kHz.
472 // there must be at least 60dB relative attenuation between stopband and passband.
473 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
474 testStopbandDownconversion<float, float>(
475 8, 48000, 32000, 12000, 20000, kQualityArray[i]);
476 }
477
478 // in this test we assume a maximum transition band between 7kHz and 15kHz.
479 // there must be at least 60dB relative attenuation between stopband and passband.
480 // (the weird ratio triggers interpolative resampling)
481 for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) {
482 testStopbandDownconversion<float, float>(
483 8, 48000, 22101, 7000, 15000, kQualityArray[i]);
484 }
485}
486