resampler_tests.cpp revision 3348e36c51e91e78020bcc6578eda83d97c31bec
1546734b3ab577d46afe863515104a062e88a109bAndy Hung/* 2546734b3ab577d46afe863515104a062e88a109bAndy Hung * Copyright (C) 2014 The Android Open Source Project 3546734b3ab577d46afe863515104a062e88a109bAndy Hung * 4546734b3ab577d46afe863515104a062e88a109bAndy Hung * Licensed under the Apache License, Version 2.0 (the "License"); 5546734b3ab577d46afe863515104a062e88a109bAndy Hung * you may not use this file except in compliance with the License. 6546734b3ab577d46afe863515104a062e88a109bAndy Hung * You may obtain a copy of the License at 7546734b3ab577d46afe863515104a062e88a109bAndy Hung * 8546734b3ab577d46afe863515104a062e88a109bAndy Hung * http://www.apache.org/licenses/LICENSE-2.0 9546734b3ab577d46afe863515104a062e88a109bAndy Hung * 10546734b3ab577d46afe863515104a062e88a109bAndy Hung * Unless required by applicable law or agreed to in writing, software 11546734b3ab577d46afe863515104a062e88a109bAndy Hung * distributed under the License is distributed on an "AS IS" BASIS, 12546734b3ab577d46afe863515104a062e88a109bAndy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13546734b3ab577d46afe863515104a062e88a109bAndy Hung * See the License for the specific language governing permissions and 14546734b3ab577d46afe863515104a062e88a109bAndy Hung * limitations under the License. 15546734b3ab577d46afe863515104a062e88a109bAndy Hung */ 16546734b3ab577d46afe863515104a062e88a109bAndy Hung 17546734b3ab577d46afe863515104a062e88a109bAndy Hung//#define LOG_NDEBUG 0 18546734b3ab577d46afe863515104a062e88a109bAndy Hung#define LOG_TAG "audioflinger_resampler_tests" 19546734b3ab577d46afe863515104a062e88a109bAndy Hung 20546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <unistd.h> 21546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <stdio.h> 22546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <stdlib.h> 23546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <fcntl.h> 24546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <string.h> 25546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <sys/mman.h> 26546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <sys/stat.h> 27546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <errno.h> 28546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <time.h> 29546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <math.h> 30546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <vector> 31546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <utility> 32546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <cutils/log.h> 33546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <gtest/gtest.h> 34546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <media/AudioBufferProvider.h> 35546734b3ab577d46afe863515104a062e88a109bAndy Hung#include "AudioResampler.h" 36c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung#include "test_utils.h" 37546734b3ab577d46afe863515104a062e88a109bAndy Hung 38075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hungvoid resample(int channels, void *output, 39075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung size_t outputFrames, const std::vector<size_t> &outputIncr, 40546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioBufferProvider *provider, android::AudioResampler *resampler) 41546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 42546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0, j = 0; i < outputFrames; ) { 43546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t thisFrames = outputIncr[j++]; 44546734b3ab577d46afe863515104a062e88a109bAndy Hung if (j >= outputIncr.size()) { 45546734b3ab577d46afe863515104a062e88a109bAndy Hung j = 0; 46546734b3ab577d46afe863515104a062e88a109bAndy Hung } 47546734b3ab577d46afe863515104a062e88a109bAndy Hung if (thisFrames == 0 || thisFrames > outputFrames - i) { 48546734b3ab577d46afe863515104a062e88a109bAndy Hung thisFrames = outputFrames - i; 49546734b3ab577d46afe863515104a062e88a109bAndy Hung } 50075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resampler->resample((int32_t*) output + channels*i, thisFrames, provider); 51546734b3ab577d46afe863515104a062e88a109bAndy Hung i += thisFrames; 52546734b3ab577d46afe863515104a062e88a109bAndy Hung } 53546734b3ab577d46afe863515104a062e88a109bAndy Hung} 54546734b3ab577d46afe863515104a062e88a109bAndy Hung 55546734b3ab577d46afe863515104a062e88a109bAndy Hungvoid buffercmp(const void *reference, const void *test, 56546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputFrameSize, size_t outputFrames) 57546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 58546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < outputFrames; ++i) { 59546734b3ab577d46afe863515104a062e88a109bAndy Hung int check = memcmp((const char*)reference + i * outputFrameSize, 60546734b3ab577d46afe863515104a062e88a109bAndy Hung (const char*)test + i * outputFrameSize, outputFrameSize); 61546734b3ab577d46afe863515104a062e88a109bAndy Hung if (check) { 62546734b3ab577d46afe863515104a062e88a109bAndy Hung ALOGE("Failure at frame %d", i); 63546734b3ab577d46afe863515104a062e88a109bAndy Hung ASSERT_EQ(check, 0); /* fails */ 64546734b3ab577d46afe863515104a062e88a109bAndy Hung } 65546734b3ab577d46afe863515104a062e88a109bAndy Hung } 66546734b3ab577d46afe863515104a062e88a109bAndy Hung} 67546734b3ab577d46afe863515104a062e88a109bAndy Hung 68075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hungvoid testBufferIncrement(size_t channels, bool useFloat, 69075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung unsigned inputFreq, unsigned outputFreq, 70546734b3ab577d46afe863515104a062e88a109bAndy Hung enum android::AudioResampler::src_quality quality) 71546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 723348e36c51e91e78020bcc6578eda83d97c31becAndy Hung const audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT; 73546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the provider 74c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung std::vector<int> inputIncr; 75c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung SignalProvider provider; 76075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung if (useFloat) { 77075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung provider.setChirp<float>(channels, 78075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 0., outputFreq/2., outputFreq, outputFreq/2000.); 79075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } else { 80075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung provider.setChirp<int16_t>(channels, 81075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 0., outputFreq/2., outputFreq, outputFreq/2000.); 82075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } 83c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung provider.setIncr(inputIncr); 84546734b3ab577d46afe863515104a062e88a109bAndy Hung 85546734b3ab577d46afe863515104a062e88a109bAndy Hung // calculate the output size 86546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq; 87075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung size_t outputFrameSize = channels * (useFloat ? sizeof(float) : sizeof(int32_t)); 88546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputSize = outputFrameSize * outputFrames; 89546734b3ab577d46afe863515104a062e88a109bAndy Hung outputSize &= ~7; 90546734b3ab577d46afe863515104a062e88a109bAndy Hung 91546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the resampler 92546734b3ab577d46afe863515104a062e88a109bAndy Hung const int volumePrecision = 12; /* typical unity gain */ 93546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler* resampler; 94546734b3ab577d46afe863515104a062e88a109bAndy Hung 953348e36c51e91e78020bcc6578eda83d97c31becAndy Hung resampler = android::AudioResampler::create(format, channels, outputFreq, quality); 96546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setSampleRate(inputFreq); 97546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setVolume(1 << volumePrecision, 1 << volumePrecision); 98546734b3ab577d46afe863515104a062e88a109bAndy Hung 99546734b3ab577d46afe863515104a062e88a109bAndy Hung // set up the reference run 100546734b3ab577d46afe863515104a062e88a109bAndy Hung std::vector<size_t> refIncr; 101546734b3ab577d46afe863515104a062e88a109bAndy Hung refIncr.push_back(outputFrames); 102546734b3ab577d46afe863515104a062e88a109bAndy Hung void* reference = malloc(outputSize); 103075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resample(channels, reference, outputFrames, refIncr, &provider, resampler); 104546734b3ab577d46afe863515104a062e88a109bAndy Hung 105546734b3ab577d46afe863515104a062e88a109bAndy Hung provider.reset(); 106546734b3ab577d46afe863515104a062e88a109bAndy Hung 107546734b3ab577d46afe863515104a062e88a109bAndy Hung#if 0 108546734b3ab577d46afe863515104a062e88a109bAndy Hung /* this test will fail - API interface issue: reset() does not clear internal buffers */ 109546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->reset(); 110546734b3ab577d46afe863515104a062e88a109bAndy Hung#else 111546734b3ab577d46afe863515104a062e88a109bAndy Hung delete resampler; 1123348e36c51e91e78020bcc6578eda83d97c31becAndy Hung resampler = android::AudioResampler::create(format, channels, outputFreq, quality); 113546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setSampleRate(inputFreq); 114546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setVolume(1 << volumePrecision, 1 << volumePrecision); 115546734b3ab577d46afe863515104a062e88a109bAndy Hung#endif 116546734b3ab577d46afe863515104a062e88a109bAndy Hung 117546734b3ab577d46afe863515104a062e88a109bAndy Hung // set up the test run 118546734b3ab577d46afe863515104a062e88a109bAndy Hung std::vector<size_t> outIncr; 119546734b3ab577d46afe863515104a062e88a109bAndy Hung outIncr.push_back(1); 120546734b3ab577d46afe863515104a062e88a109bAndy Hung outIncr.push_back(2); 121546734b3ab577d46afe863515104a062e88a109bAndy Hung outIncr.push_back(3); 122546734b3ab577d46afe863515104a062e88a109bAndy Hung void* test = malloc(outputSize); 123075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung inputIncr.push_back(1); 124075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung inputIncr.push_back(3); 125075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung provider.setIncr(inputIncr); 126075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resample(channels, test, outputFrames, outIncr, &provider, resampler); 127546734b3ab577d46afe863515104a062e88a109bAndy Hung 128546734b3ab577d46afe863515104a062e88a109bAndy Hung // check 129546734b3ab577d46afe863515104a062e88a109bAndy Hung buffercmp(reference, test, outputFrameSize, outputFrames); 130546734b3ab577d46afe863515104a062e88a109bAndy Hung 131546734b3ab577d46afe863515104a062e88a109bAndy Hung free(reference); 132546734b3ab577d46afe863515104a062e88a109bAndy Hung free(test); 133546734b3ab577d46afe863515104a062e88a109bAndy Hung delete resampler; 134546734b3ab577d46afe863515104a062e88a109bAndy Hung} 135546734b3ab577d46afe863515104a062e88a109bAndy Hung 136546734b3ab577d46afe863515104a062e88a109bAndy Hungtemplate <typename T> 137546734b3ab577d46afe863515104a062e88a109bAndy Hunginline double sqr(T v) 138546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 139546734b3ab577d46afe863515104a062e88a109bAndy Hung double dv = static_cast<double>(v); 140546734b3ab577d46afe863515104a062e88a109bAndy Hung return dv * dv; 141546734b3ab577d46afe863515104a062e88a109bAndy Hung} 142546734b3ab577d46afe863515104a062e88a109bAndy Hung 143546734b3ab577d46afe863515104a062e88a109bAndy Hungtemplate <typename T> 144546734b3ab577d46afe863515104a062e88a109bAndy Hungdouble signalEnergy(T *start, T *end, unsigned stride) 145546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 146546734b3ab577d46afe863515104a062e88a109bAndy Hung double accum = 0; 147546734b3ab577d46afe863515104a062e88a109bAndy Hung 148546734b3ab577d46afe863515104a062e88a109bAndy Hung for (T *p = start; p < end; p += stride) { 149546734b3ab577d46afe863515104a062e88a109bAndy Hung accum += sqr(*p); 150546734b3ab577d46afe863515104a062e88a109bAndy Hung } 151546734b3ab577d46afe863515104a062e88a109bAndy Hung unsigned count = (end - start + stride - 1) / stride; 152546734b3ab577d46afe863515104a062e88a109bAndy Hung return accum / count; 153546734b3ab577d46afe863515104a062e88a109bAndy Hung} 154546734b3ab577d46afe863515104a062e88a109bAndy Hung 155546734b3ab577d46afe863515104a062e88a109bAndy Hungvoid testStopbandDownconversion(size_t channels, 156546734b3ab577d46afe863515104a062e88a109bAndy Hung unsigned inputFreq, unsigned outputFreq, 157546734b3ab577d46afe863515104a062e88a109bAndy Hung unsigned passband, unsigned stopband, 158546734b3ab577d46afe863515104a062e88a109bAndy Hung enum android::AudioResampler::src_quality quality) 159546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 160546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the provider 161c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung std::vector<int> inputIncr; 162c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung SignalProvider provider; 163c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung provider.setChirp<int16_t>(channels, 164c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung 0., inputFreq/2., inputFreq, inputFreq/2000.); 165c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung provider.setIncr(inputIncr); 166546734b3ab577d46afe863515104a062e88a109bAndy Hung 167546734b3ab577d46afe863515104a062e88a109bAndy Hung // calculate the output size 168546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq; 169075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung size_t outputFrameSize = channels * sizeof(int32_t); 170546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputSize = outputFrameSize * outputFrames; 171546734b3ab577d46afe863515104a062e88a109bAndy Hung outputSize &= ~7; 172546734b3ab577d46afe863515104a062e88a109bAndy Hung 173546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the resampler 174546734b3ab577d46afe863515104a062e88a109bAndy Hung const int volumePrecision = 12; /* typical unity gain */ 175546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler* resampler; 176546734b3ab577d46afe863515104a062e88a109bAndy Hung 1773348e36c51e91e78020bcc6578eda83d97c31becAndy Hung resampler = android::AudioResampler::create(AUDIO_FORMAT_PCM_16_BIT, 1783348e36c51e91e78020bcc6578eda83d97c31becAndy Hung channels, outputFreq, quality); 179546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setSampleRate(inputFreq); 180546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setVolume(1 << volumePrecision, 1 << volumePrecision); 181546734b3ab577d46afe863515104a062e88a109bAndy Hung 182546734b3ab577d46afe863515104a062e88a109bAndy Hung // set up the reference run 183546734b3ab577d46afe863515104a062e88a109bAndy Hung std::vector<size_t> refIncr; 184546734b3ab577d46afe863515104a062e88a109bAndy Hung refIncr.push_back(outputFrames); 185546734b3ab577d46afe863515104a062e88a109bAndy Hung void* reference = malloc(outputSize); 186075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resample(channels, reference, outputFrames, refIncr, &provider, resampler); 187546734b3ab577d46afe863515104a062e88a109bAndy Hung 188546734b3ab577d46afe863515104a062e88a109bAndy Hung int32_t *out = reinterpret_cast<int32_t *>(reference); 189546734b3ab577d46afe863515104a062e88a109bAndy Hung 190546734b3ab577d46afe863515104a062e88a109bAndy Hung // check signal energy in passband 191546734b3ab577d46afe863515104a062e88a109bAndy Hung const unsigned passbandFrame = passband * outputFreq / 1000.; 192546734b3ab577d46afe863515104a062e88a109bAndy Hung const unsigned stopbandFrame = stopband * outputFreq / 1000.; 193546734b3ab577d46afe863515104a062e88a109bAndy Hung 194546734b3ab577d46afe863515104a062e88a109bAndy Hung // check each channel separately 195546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < channels; ++i) { 196546734b3ab577d46afe863515104a062e88a109bAndy Hung double passbandEnergy = signalEnergy(out, out + passbandFrame * channels, channels); 197546734b3ab577d46afe863515104a062e88a109bAndy Hung double stopbandEnergy = signalEnergy(out + stopbandFrame * channels, 198546734b3ab577d46afe863515104a062e88a109bAndy Hung out + outputFrames * channels, channels); 199546734b3ab577d46afe863515104a062e88a109bAndy Hung double dbAtten = -10. * log10(stopbandEnergy / passbandEnergy); 200546734b3ab577d46afe863515104a062e88a109bAndy Hung ASSERT_GT(dbAtten, 60.); 201546734b3ab577d46afe863515104a062e88a109bAndy Hung 202546734b3ab577d46afe863515104a062e88a109bAndy Hung#if 0 203546734b3ab577d46afe863515104a062e88a109bAndy Hung // internal verification 204546734b3ab577d46afe863515104a062e88a109bAndy Hung printf("if:%d of:%d pbf:%d sbf:%d sbe: %f pbe: %f db: %.2f\n", 205546734b3ab577d46afe863515104a062e88a109bAndy Hung provider.getNumFrames(), outputFrames, 206546734b3ab577d46afe863515104a062e88a109bAndy Hung passbandFrame, stopbandFrame, stopbandEnergy, passbandEnergy, dbAtten); 207546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < 10; ++i) { 208546734b3ab577d46afe863515104a062e88a109bAndy Hung printf("%d\n", out[i+passbandFrame*channels]); 209546734b3ab577d46afe863515104a062e88a109bAndy Hung } 210546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < 10; ++i) { 211546734b3ab577d46afe863515104a062e88a109bAndy Hung printf("%d\n", out[i+stopbandFrame*channels]); 212546734b3ab577d46afe863515104a062e88a109bAndy Hung } 213546734b3ab577d46afe863515104a062e88a109bAndy Hung#endif 214546734b3ab577d46afe863515104a062e88a109bAndy Hung } 215546734b3ab577d46afe863515104a062e88a109bAndy Hung 216546734b3ab577d46afe863515104a062e88a109bAndy Hung free(reference); 217546734b3ab577d46afe863515104a062e88a109bAndy Hung delete resampler; 218546734b3ab577d46afe863515104a062e88a109bAndy Hung} 219546734b3ab577d46afe863515104a062e88a109bAndy Hung 220546734b3ab577d46afe863515104a062e88a109bAndy Hung/* Buffer increment test 221546734b3ab577d46afe863515104a062e88a109bAndy Hung * 222546734b3ab577d46afe863515104a062e88a109bAndy Hung * We compare a reference output, where we consume and process the entire 223546734b3ab577d46afe863515104a062e88a109bAndy Hung * buffer at a time, and a test output, where we provide small chunks of input 224546734b3ab577d46afe863515104a062e88a109bAndy Hung * data and process small chunks of output (which may not be equivalent in size). 225546734b3ab577d46afe863515104a062e88a109bAndy Hung * 226546734b3ab577d46afe863515104a062e88a109bAndy Hung * Two subtests - fixed phase (3:2 down) and interpolated phase (147:320 up) 227546734b3ab577d46afe863515104a062e88a109bAndy Hung */ 228546734b3ab577d46afe863515104a062e88a109bAndy HungTEST(audioflinger_resampler, bufferincrement_fixedphase) { 229546734b3ab577d46afe863515104a062e88a109bAndy Hung // all of these work 230546734b3ab577d46afe863515104a062e88a109bAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 231546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::LOW_QUALITY, 232546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::MED_QUALITY, 233546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::HIGH_QUALITY, 234546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::VERY_HIGH_QUALITY, 235546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 236546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_MED_QUALITY, 237546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 238546734b3ab577d46afe863515104a062e88a109bAndy Hung }; 239546734b3ab577d46afe863515104a062e88a109bAndy Hung 240546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 241075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(2, false, 48000, 32000, kQualityArray[i]); 242546734b3ab577d46afe863515104a062e88a109bAndy Hung } 243546734b3ab577d46afe863515104a062e88a109bAndy Hung} 244546734b3ab577d46afe863515104a062e88a109bAndy Hung 245546734b3ab577d46afe863515104a062e88a109bAndy HungTEST(audioflinger_resampler, bufferincrement_interpolatedphase) { 246546734b3ab577d46afe863515104a062e88a109bAndy Hung // all of these work except low quality 247546734b3ab577d46afe863515104a062e88a109bAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 248546734b3ab577d46afe863515104a062e88a109bAndy Hung// android::AudioResampler::LOW_QUALITY, 249546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::MED_QUALITY, 250546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::HIGH_QUALITY, 251546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::VERY_HIGH_QUALITY, 252546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 253546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_MED_QUALITY, 254546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 255546734b3ab577d46afe863515104a062e88a109bAndy Hung }; 256546734b3ab577d46afe863515104a062e88a109bAndy Hung 257546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 258075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(2, false, 22050, 48000, kQualityArray[i]); 259075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } 260075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung} 261075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 262075abae2a954bf3edf18ad1705c2c0f188454ae0Andy HungTEST(audioflinger_resampler, bufferincrement_fixedphase_multi) { 263075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung // only dynamic quality 264075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 265075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_LOW_QUALITY, 266075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_MED_QUALITY, 267075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_HIGH_QUALITY, 268075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung }; 269075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 270075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 271075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(4, false, 48000, 32000, kQualityArray[i]); 272075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } 273075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung} 274075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 275075abae2a954bf3edf18ad1705c2c0f188454ae0Andy HungTEST(audioflinger_resampler, bufferincrement_interpolatedphase_multi_float) { 276075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung // only dynamic quality 277075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 278075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_LOW_QUALITY, 279075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_MED_QUALITY, 280075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_HIGH_QUALITY, 281075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung }; 282075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 283075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 284075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(8, true, 22050, 48000, kQualityArray[i]); 285546734b3ab577d46afe863515104a062e88a109bAndy Hung } 286546734b3ab577d46afe863515104a062e88a109bAndy Hung} 287546734b3ab577d46afe863515104a062e88a109bAndy Hung 288546734b3ab577d46afe863515104a062e88a109bAndy Hung/* Simple aliasing test 289546734b3ab577d46afe863515104a062e88a109bAndy Hung * 290546734b3ab577d46afe863515104a062e88a109bAndy Hung * This checks stopband response of the chirp signal to make sure frequencies 291546734b3ab577d46afe863515104a062e88a109bAndy Hung * are properly suppressed. It uses downsampling because the stopband can be 292546734b3ab577d46afe863515104a062e88a109bAndy Hung * clearly isolated by input frequencies exceeding the output sample rate (nyquist). 293546734b3ab577d46afe863515104a062e88a109bAndy Hung */ 294546734b3ab577d46afe863515104a062e88a109bAndy HungTEST(audioflinger_resampler, stopbandresponse) { 295546734b3ab577d46afe863515104a062e88a109bAndy Hung // not all of these may work (old resamplers fail on downsampling) 296546734b3ab577d46afe863515104a062e88a109bAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 297546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::LOW_QUALITY, 298546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::MED_QUALITY, 299546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::HIGH_QUALITY, 300546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::VERY_HIGH_QUALITY, 301546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 302546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_MED_QUALITY, 303546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 304546734b3ab577d46afe863515104a062e88a109bAndy Hung }; 305546734b3ab577d46afe863515104a062e88a109bAndy Hung 306546734b3ab577d46afe863515104a062e88a109bAndy Hung // in this test we assume a maximum transition band between 12kHz and 20kHz. 307546734b3ab577d46afe863515104a062e88a109bAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 308546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 309546734b3ab577d46afe863515104a062e88a109bAndy Hung testStopbandDownconversion(2, 48000, 32000, 12000, 20000, kQualityArray[i]); 310546734b3ab577d46afe863515104a062e88a109bAndy Hung } 311546734b3ab577d46afe863515104a062e88a109bAndy Hung 312546734b3ab577d46afe863515104a062e88a109bAndy Hung // in this test we assume a maximum transition band between 7kHz and 15kHz. 313546734b3ab577d46afe863515104a062e88a109bAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 314546734b3ab577d46afe863515104a062e88a109bAndy Hung // (the weird ratio triggers interpolative resampling) 315546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 316546734b3ab577d46afe863515104a062e88a109bAndy Hung testStopbandDownconversion(2, 48000, 22101, 7000, 15000, kQualityArray[i]); 317546734b3ab577d46afe863515104a062e88a109bAndy Hung } 318546734b3ab577d46afe863515104a062e88a109bAndy Hung} 319