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> 3242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung#include <iostream> 33546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <cutils/log.h> 34546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <gtest/gtest.h> 35546734b3ab577d46afe863515104a062e88a109bAndy Hung#include <media/AudioBufferProvider.h> 36546734b3ab577d46afe863515104a062e88a109bAndy Hung#include "AudioResampler.h" 37c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung#include "test_utils.h" 38546734b3ab577d46afe863515104a062e88a109bAndy Hung 39075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hungvoid resample(int channels, void *output, 40075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung size_t outputFrames, const std::vector<size_t> &outputIncr, 41546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioBufferProvider *provider, android::AudioResampler *resampler) 42546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 43546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0, j = 0; i < outputFrames; ) { 44546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t thisFrames = outputIncr[j++]; 45546734b3ab577d46afe863515104a062e88a109bAndy Hung if (j >= outputIncr.size()) { 46546734b3ab577d46afe863515104a062e88a109bAndy Hung j = 0; 47546734b3ab577d46afe863515104a062e88a109bAndy Hung } 48546734b3ab577d46afe863515104a062e88a109bAndy Hung if (thisFrames == 0 || thisFrames > outputFrames - i) { 49546734b3ab577d46afe863515104a062e88a109bAndy Hung thisFrames = outputFrames - i; 50546734b3ab577d46afe863515104a062e88a109bAndy Hung } 516b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung size_t framesResampled = resampler->resample( 526b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung (int32_t*) output + channels*i, thisFrames, provider); 536b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung // we should have enough buffer space, so there is no short count. 546b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung ASSERT_EQ(thisFrames, framesResampled); 55546734b3ab577d46afe863515104a062e88a109bAndy Hung i += thisFrames; 56546734b3ab577d46afe863515104a062e88a109bAndy Hung } 57546734b3ab577d46afe863515104a062e88a109bAndy Hung} 58546734b3ab577d46afe863515104a062e88a109bAndy Hung 59546734b3ab577d46afe863515104a062e88a109bAndy Hungvoid buffercmp(const void *reference, const void *test, 60546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputFrameSize, size_t outputFrames) 61546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 62546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < outputFrames; ++i) { 63546734b3ab577d46afe863515104a062e88a109bAndy Hung int check = memcmp((const char*)reference + i * outputFrameSize, 64546734b3ab577d46afe863515104a062e88a109bAndy Hung (const char*)test + i * outputFrameSize, outputFrameSize); 65546734b3ab577d46afe863515104a062e88a109bAndy Hung if (check) { 66a4daf0b4f934b800a49f199fb8c09409391c8fc0Glenn Kasten ALOGE("Failure at frame %zu", i); 67546734b3ab577d46afe863515104a062e88a109bAndy Hung ASSERT_EQ(check, 0); /* fails */ 68546734b3ab577d46afe863515104a062e88a109bAndy Hung } 69546734b3ab577d46afe863515104a062e88a109bAndy Hung } 70546734b3ab577d46afe863515104a062e88a109bAndy Hung} 71546734b3ab577d46afe863515104a062e88a109bAndy Hung 72075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hungvoid testBufferIncrement(size_t channels, bool useFloat, 73075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung unsigned inputFreq, unsigned outputFreq, 74546734b3ab577d46afe863515104a062e88a109bAndy Hung enum android::AudioResampler::src_quality quality) 75546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 763348e36c51e91e78020bcc6578eda83d97c31becAndy Hung const audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT; 77546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the provider 78c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung std::vector<int> inputIncr; 79c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung SignalProvider provider; 80075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung if (useFloat) { 81075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung provider.setChirp<float>(channels, 82075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 0., outputFreq/2., outputFreq, outputFreq/2000.); 83075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } else { 84075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung provider.setChirp<int16_t>(channels, 85075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 0., outputFreq/2., outputFreq, outputFreq/2000.); 86075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } 87c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung provider.setIncr(inputIncr); 88546734b3ab577d46afe863515104a062e88a109bAndy Hung 89546734b3ab577d46afe863515104a062e88a109bAndy Hung // calculate the output size 90546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq; 91075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung size_t outputFrameSize = channels * (useFloat ? sizeof(float) : sizeof(int32_t)); 92546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputSize = outputFrameSize * outputFrames; 93546734b3ab577d46afe863515104a062e88a109bAndy Hung outputSize &= ~7; 94546734b3ab577d46afe863515104a062e88a109bAndy Hung 95546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the resampler 96546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler* resampler; 97546734b3ab577d46afe863515104a062e88a109bAndy Hung 983348e36c51e91e78020bcc6578eda83d97c31becAndy Hung resampler = android::AudioResampler::create(format, channels, outputFreq, quality); 99546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setSampleRate(inputFreq); 1005e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung resampler->setVolume(android::AudioResampler::UNITY_GAIN_FLOAT, 1015e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung android::AudioResampler::UNITY_GAIN_FLOAT); 102546734b3ab577d46afe863515104a062e88a109bAndy Hung 103546734b3ab577d46afe863515104a062e88a109bAndy Hung // set up the reference run 104546734b3ab577d46afe863515104a062e88a109bAndy Hung std::vector<size_t> refIncr; 105546734b3ab577d46afe863515104a062e88a109bAndy Hung refIncr.push_back(outputFrames); 106546734b3ab577d46afe863515104a062e88a109bAndy Hung void* reference = malloc(outputSize); 107075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resample(channels, reference, outputFrames, refIncr, &provider, resampler); 108546734b3ab577d46afe863515104a062e88a109bAndy Hung 109546734b3ab577d46afe863515104a062e88a109bAndy Hung provider.reset(); 110546734b3ab577d46afe863515104a062e88a109bAndy Hung 111546734b3ab577d46afe863515104a062e88a109bAndy Hung#if 0 112546734b3ab577d46afe863515104a062e88a109bAndy Hung /* this test will fail - API interface issue: reset() does not clear internal buffers */ 113546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->reset(); 114546734b3ab577d46afe863515104a062e88a109bAndy Hung#else 115546734b3ab577d46afe863515104a062e88a109bAndy Hung delete resampler; 1163348e36c51e91e78020bcc6578eda83d97c31becAndy Hung resampler = android::AudioResampler::create(format, channels, outputFreq, quality); 117546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setSampleRate(inputFreq); 1185e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung resampler->setVolume(android::AudioResampler::UNITY_GAIN_FLOAT, 1195e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung android::AudioResampler::UNITY_GAIN_FLOAT); 120546734b3ab577d46afe863515104a062e88a109bAndy Hung#endif 121546734b3ab577d46afe863515104a062e88a109bAndy Hung 122546734b3ab577d46afe863515104a062e88a109bAndy Hung // set up the test run 123546734b3ab577d46afe863515104a062e88a109bAndy Hung std::vector<size_t> outIncr; 124546734b3ab577d46afe863515104a062e88a109bAndy Hung outIncr.push_back(1); 125546734b3ab577d46afe863515104a062e88a109bAndy Hung outIncr.push_back(2); 126546734b3ab577d46afe863515104a062e88a109bAndy Hung outIncr.push_back(3); 127546734b3ab577d46afe863515104a062e88a109bAndy Hung void* test = malloc(outputSize); 128075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung inputIncr.push_back(1); 129075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung inputIncr.push_back(3); 130075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung provider.setIncr(inputIncr); 131075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resample(channels, test, outputFrames, outIncr, &provider, resampler); 132546734b3ab577d46afe863515104a062e88a109bAndy Hung 133546734b3ab577d46afe863515104a062e88a109bAndy Hung // check 134546734b3ab577d46afe863515104a062e88a109bAndy Hung buffercmp(reference, test, outputFrameSize, outputFrames); 135546734b3ab577d46afe863515104a062e88a109bAndy Hung 136546734b3ab577d46afe863515104a062e88a109bAndy Hung free(reference); 137546734b3ab577d46afe863515104a062e88a109bAndy Hung free(test); 138546734b3ab577d46afe863515104a062e88a109bAndy Hung delete resampler; 139546734b3ab577d46afe863515104a062e88a109bAndy Hung} 140546734b3ab577d46afe863515104a062e88a109bAndy Hung 141546734b3ab577d46afe863515104a062e88a109bAndy Hungtemplate <typename T> 142546734b3ab577d46afe863515104a062e88a109bAndy Hunginline double sqr(T v) 143546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 144546734b3ab577d46afe863515104a062e88a109bAndy Hung double dv = static_cast<double>(v); 145546734b3ab577d46afe863515104a062e88a109bAndy Hung return dv * dv; 146546734b3ab577d46afe863515104a062e88a109bAndy Hung} 147546734b3ab577d46afe863515104a062e88a109bAndy Hung 148546734b3ab577d46afe863515104a062e88a109bAndy Hungtemplate <typename T> 149546734b3ab577d46afe863515104a062e88a109bAndy Hungdouble signalEnergy(T *start, T *end, unsigned stride) 150546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 151546734b3ab577d46afe863515104a062e88a109bAndy Hung double accum = 0; 152546734b3ab577d46afe863515104a062e88a109bAndy Hung 153546734b3ab577d46afe863515104a062e88a109bAndy Hung for (T *p = start; p < end; p += stride) { 154546734b3ab577d46afe863515104a062e88a109bAndy Hung accum += sqr(*p); 155546734b3ab577d46afe863515104a062e88a109bAndy Hung } 156546734b3ab577d46afe863515104a062e88a109bAndy Hung unsigned count = (end - start + stride - 1) / stride; 157546734b3ab577d46afe863515104a062e88a109bAndy Hung return accum / count; 158546734b3ab577d46afe863515104a062e88a109bAndy Hung} 159546734b3ab577d46afe863515104a062e88a109bAndy Hung 16042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung// TI = resampler input type, int16_t or float 16142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung// TO = resampler output type, int32_t or float 16242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hungtemplate <typename TI, typename TO> 163546734b3ab577d46afe863515104a062e88a109bAndy Hungvoid testStopbandDownconversion(size_t channels, 164546734b3ab577d46afe863515104a062e88a109bAndy Hung unsigned inputFreq, unsigned outputFreq, 165546734b3ab577d46afe863515104a062e88a109bAndy Hung unsigned passband, unsigned stopband, 166546734b3ab577d46afe863515104a062e88a109bAndy Hung enum android::AudioResampler::src_quality quality) 167546734b3ab577d46afe863515104a062e88a109bAndy Hung{ 168546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the provider 169c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung std::vector<int> inputIncr; 170c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung SignalProvider provider; 17142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung provider.setChirp<TI>(channels, 172c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung 0., inputFreq/2., inputFreq, inputFreq/2000.); 173c0e5ec8e2d8db15b97094374d0a248e041304b62Andy Hung provider.setIncr(inputIncr); 174546734b3ab577d46afe863515104a062e88a109bAndy Hung 175546734b3ab577d46afe863515104a062e88a109bAndy Hung // calculate the output size 176546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputFrames = ((int64_t) provider.getNumFrames() * outputFreq) / inputFreq; 17742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung size_t outputFrameSize = channels * sizeof(TO); 178546734b3ab577d46afe863515104a062e88a109bAndy Hung size_t outputSize = outputFrameSize * outputFrames; 179546734b3ab577d46afe863515104a062e88a109bAndy Hung outputSize &= ~7; 180546734b3ab577d46afe863515104a062e88a109bAndy Hung 181546734b3ab577d46afe863515104a062e88a109bAndy Hung // create the resampler 182546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler* resampler; 183546734b3ab577d46afe863515104a062e88a109bAndy Hung 18442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung resampler = android::AudioResampler::create( 18542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung is_same<TI, int16_t>::value ? AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT, 1863348e36c51e91e78020bcc6578eda83d97c31becAndy Hung channels, outputFreq, quality); 187546734b3ab577d46afe863515104a062e88a109bAndy Hung resampler->setSampleRate(inputFreq); 1885e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung resampler->setVolume(android::AudioResampler::UNITY_GAIN_FLOAT, 1895e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung android::AudioResampler::UNITY_GAIN_FLOAT); 190546734b3ab577d46afe863515104a062e88a109bAndy Hung 191546734b3ab577d46afe863515104a062e88a109bAndy Hung // set up the reference run 192546734b3ab577d46afe863515104a062e88a109bAndy Hung std::vector<size_t> refIncr; 193546734b3ab577d46afe863515104a062e88a109bAndy Hung refIncr.push_back(outputFrames); 194546734b3ab577d46afe863515104a062e88a109bAndy Hung void* reference = malloc(outputSize); 195075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung resample(channels, reference, outputFrames, refIncr, &provider, resampler); 196546734b3ab577d46afe863515104a062e88a109bAndy Hung 19742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung TO *out = reinterpret_cast<TO *>(reference); 198546734b3ab577d46afe863515104a062e88a109bAndy Hung 199546734b3ab577d46afe863515104a062e88a109bAndy Hung // check signal energy in passband 200546734b3ab577d46afe863515104a062e88a109bAndy Hung const unsigned passbandFrame = passband * outputFreq / 1000.; 201546734b3ab577d46afe863515104a062e88a109bAndy Hung const unsigned stopbandFrame = stopband * outputFreq / 1000.; 202546734b3ab577d46afe863515104a062e88a109bAndy Hung 203546734b3ab577d46afe863515104a062e88a109bAndy Hung // check each channel separately 204546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < channels; ++i) { 205546734b3ab577d46afe863515104a062e88a109bAndy Hung double passbandEnergy = signalEnergy(out, out + passbandFrame * channels, channels); 206546734b3ab577d46afe863515104a062e88a109bAndy Hung double stopbandEnergy = signalEnergy(out + stopbandFrame * channels, 207546734b3ab577d46afe863515104a062e88a109bAndy Hung out + outputFrames * channels, channels); 208546734b3ab577d46afe863515104a062e88a109bAndy Hung double dbAtten = -10. * log10(stopbandEnergy / passbandEnergy); 209546734b3ab577d46afe863515104a062e88a109bAndy Hung ASSERT_GT(dbAtten, 60.); 210546734b3ab577d46afe863515104a062e88a109bAndy Hung 211546734b3ab577d46afe863515104a062e88a109bAndy Hung#if 0 212546734b3ab577d46afe863515104a062e88a109bAndy Hung // internal verification 213546734b3ab577d46afe863515104a062e88a109bAndy Hung printf("if:%d of:%d pbf:%d sbf:%d sbe: %f pbe: %f db: %.2f\n", 214546734b3ab577d46afe863515104a062e88a109bAndy Hung provider.getNumFrames(), outputFrames, 215546734b3ab577d46afe863515104a062e88a109bAndy Hung passbandFrame, stopbandFrame, stopbandEnergy, passbandEnergy, dbAtten); 216546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < 10; ++i) { 21742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung std::cout << out[i+passbandFrame*channels] << std::endl; 218546734b3ab577d46afe863515104a062e88a109bAndy Hung } 219546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < 10; ++i) { 22042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung std::cout << out[i+stopbandFrame*channels] << std::endl; 221546734b3ab577d46afe863515104a062e88a109bAndy Hung } 222546734b3ab577d46afe863515104a062e88a109bAndy Hung#endif 223546734b3ab577d46afe863515104a062e88a109bAndy Hung } 224546734b3ab577d46afe863515104a062e88a109bAndy Hung 225546734b3ab577d46afe863515104a062e88a109bAndy Hung free(reference); 226546734b3ab577d46afe863515104a062e88a109bAndy Hung delete resampler; 227546734b3ab577d46afe863515104a062e88a109bAndy Hung} 228546734b3ab577d46afe863515104a062e88a109bAndy Hung 229546734b3ab577d46afe863515104a062e88a109bAndy Hung/* Buffer increment test 230546734b3ab577d46afe863515104a062e88a109bAndy Hung * 231546734b3ab577d46afe863515104a062e88a109bAndy Hung * We compare a reference output, where we consume and process the entire 232546734b3ab577d46afe863515104a062e88a109bAndy Hung * buffer at a time, and a test output, where we provide small chunks of input 233546734b3ab577d46afe863515104a062e88a109bAndy Hung * data and process small chunks of output (which may not be equivalent in size). 234546734b3ab577d46afe863515104a062e88a109bAndy Hung * 235546734b3ab577d46afe863515104a062e88a109bAndy Hung * Two subtests - fixed phase (3:2 down) and interpolated phase (147:320 up) 236546734b3ab577d46afe863515104a062e88a109bAndy Hung */ 237546734b3ab577d46afe863515104a062e88a109bAndy HungTEST(audioflinger_resampler, bufferincrement_fixedphase) { 238546734b3ab577d46afe863515104a062e88a109bAndy Hung // all of these work 239546734b3ab577d46afe863515104a062e88a109bAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 240546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::LOW_QUALITY, 241546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::MED_QUALITY, 242546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::HIGH_QUALITY, 243546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::VERY_HIGH_QUALITY, 244546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 245546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_MED_QUALITY, 246546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 247546734b3ab577d46afe863515104a062e88a109bAndy Hung }; 248546734b3ab577d46afe863515104a062e88a109bAndy Hung 249546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 250075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(2, false, 48000, 32000, kQualityArray[i]); 251546734b3ab577d46afe863515104a062e88a109bAndy Hung } 252546734b3ab577d46afe863515104a062e88a109bAndy Hung} 253546734b3ab577d46afe863515104a062e88a109bAndy Hung 254546734b3ab577d46afe863515104a062e88a109bAndy HungTEST(audioflinger_resampler, bufferincrement_interpolatedphase) { 255546734b3ab577d46afe863515104a062e88a109bAndy Hung // all of these work except low quality 256546734b3ab577d46afe863515104a062e88a109bAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 257546734b3ab577d46afe863515104a062e88a109bAndy Hung// android::AudioResampler::LOW_QUALITY, 258546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::MED_QUALITY, 259546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::HIGH_QUALITY, 260546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::VERY_HIGH_QUALITY, 261546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 262546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_MED_QUALITY, 263546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 264546734b3ab577d46afe863515104a062e88a109bAndy Hung }; 265546734b3ab577d46afe863515104a062e88a109bAndy Hung 266546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 267075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(2, false, 22050, 48000, kQualityArray[i]); 268075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } 269075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung} 270075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 271075abae2a954bf3edf18ad1705c2c0f188454ae0Andy HungTEST(audioflinger_resampler, bufferincrement_fixedphase_multi) { 272075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung // only dynamic quality 273075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 274075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_LOW_QUALITY, 275075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_MED_QUALITY, 276075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_HIGH_QUALITY, 277075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung }; 278075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 279075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 280075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(4, false, 48000, 32000, kQualityArray[i]); 281075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung } 282075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung} 283075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 284075abae2a954bf3edf18ad1705c2c0f188454ae0Andy HungTEST(audioflinger_resampler, bufferincrement_interpolatedphase_multi_float) { 285075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung // only dynamic quality 286075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 287075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_LOW_QUALITY, 288075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_MED_QUALITY, 289075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung android::AudioResampler::DYN_HIGH_QUALITY, 290075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung }; 291075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung 292075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 293075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung testBufferIncrement(8, true, 22050, 48000, kQualityArray[i]); 294546734b3ab577d46afe863515104a062e88a109bAndy Hung } 295546734b3ab577d46afe863515104a062e88a109bAndy Hung} 296546734b3ab577d46afe863515104a062e88a109bAndy Hung 297546734b3ab577d46afe863515104a062e88a109bAndy Hung/* Simple aliasing test 298546734b3ab577d46afe863515104a062e88a109bAndy Hung * 299546734b3ab577d46afe863515104a062e88a109bAndy Hung * This checks stopband response of the chirp signal to make sure frequencies 300546734b3ab577d46afe863515104a062e88a109bAndy Hung * are properly suppressed. It uses downsampling because the stopband can be 301546734b3ab577d46afe863515104a062e88a109bAndy Hung * clearly isolated by input frequencies exceeding the output sample rate (nyquist). 302546734b3ab577d46afe863515104a062e88a109bAndy Hung */ 30342b011166ece30969667e0ff9dcf4832568c9c1aAndy HungTEST(audioflinger_resampler, stopbandresponse_integer) { 304546734b3ab577d46afe863515104a062e88a109bAndy Hung // not all of these may work (old resamplers fail on downsampling) 305546734b3ab577d46afe863515104a062e88a109bAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 306546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::LOW_QUALITY, 307546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::MED_QUALITY, 308546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::HIGH_QUALITY, 309546734b3ab577d46afe863515104a062e88a109bAndy Hung //android::AudioResampler::VERY_HIGH_QUALITY, 310546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 311546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_MED_QUALITY, 312546734b3ab577d46afe863515104a062e88a109bAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 313546734b3ab577d46afe863515104a062e88a109bAndy Hung }; 314546734b3ab577d46afe863515104a062e88a109bAndy Hung 315546734b3ab577d46afe863515104a062e88a109bAndy Hung // in this test we assume a maximum transition band between 12kHz and 20kHz. 316546734b3ab577d46afe863515104a062e88a109bAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 317546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 31842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<int16_t, int32_t>( 31942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 2, 48000, 32000, 12000, 20000, kQualityArray[i]); 320546734b3ab577d46afe863515104a062e88a109bAndy Hung } 321546734b3ab577d46afe863515104a062e88a109bAndy Hung 322546734b3ab577d46afe863515104a062e88a109bAndy Hung // in this test we assume a maximum transition band between 7kHz and 15kHz. 323546734b3ab577d46afe863515104a062e88a109bAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 324546734b3ab577d46afe863515104a062e88a109bAndy Hung // (the weird ratio triggers interpolative resampling) 325546734b3ab577d46afe863515104a062e88a109bAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 32642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<int16_t, int32_t>( 32742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 2, 48000, 22101, 7000, 15000, kQualityArray[i]); 328546734b3ab577d46afe863515104a062e88a109bAndy Hung } 329546734b3ab577d46afe863515104a062e88a109bAndy Hung} 33042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 33142b011166ece30969667e0ff9dcf4832568c9c1aAndy HungTEST(audioflinger_resampler, stopbandresponse_integer_multichannel) { 33242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // not all of these may work (old resamplers fail on downsampling) 33342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 33442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::LOW_QUALITY, 33542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::MED_QUALITY, 33642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::HIGH_QUALITY, 33742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::VERY_HIGH_QUALITY, 33842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 33942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_MED_QUALITY, 34042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 34142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung }; 34242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 34342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // in this test we assume a maximum transition band between 12kHz and 20kHz. 34442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 34542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 34642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<int16_t, int32_t>( 34742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 8, 48000, 32000, 12000, 20000, kQualityArray[i]); 34842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung } 34942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 35042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // in this test we assume a maximum transition band between 7kHz and 15kHz. 35142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 35242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // (the weird ratio triggers interpolative resampling) 35342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 35442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<int16_t, int32_t>( 35542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 8, 48000, 22101, 7000, 15000, kQualityArray[i]); 35642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung } 35742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung} 35842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 35942b011166ece30969667e0ff9dcf4832568c9c1aAndy HungTEST(audioflinger_resampler, stopbandresponse_float) { 36042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // not all of these may work (old resamplers fail on downsampling) 36142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 36242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::LOW_QUALITY, 36342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::MED_QUALITY, 36442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::HIGH_QUALITY, 36542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::VERY_HIGH_QUALITY, 36642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 36742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_MED_QUALITY, 36842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 36942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung }; 37042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 37142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // in this test we assume a maximum transition band between 12kHz and 20kHz. 37242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 37342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 37442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<float, float>( 37542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 2, 48000, 32000, 12000, 20000, kQualityArray[i]); 37642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung } 37742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 37842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // in this test we assume a maximum transition band between 7kHz and 15kHz. 37942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 38042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // (the weird ratio triggers interpolative resampling) 38142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 38242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<float, float>( 38342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 2, 48000, 22101, 7000, 15000, kQualityArray[i]); 38442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung } 38542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung} 38642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 38742b011166ece30969667e0ff9dcf4832568c9c1aAndy HungTEST(audioflinger_resampler, stopbandresponse_float_multichannel) { 38842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // not all of these may work (old resamplers fail on downsampling) 38942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung static const enum android::AudioResampler::src_quality kQualityArray[] = { 39042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::LOW_QUALITY, 39142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::MED_QUALITY, 39242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::HIGH_QUALITY, 39342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung //android::AudioResampler::VERY_HIGH_QUALITY, 39442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_LOW_QUALITY, 39542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_MED_QUALITY, 39642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung android::AudioResampler::DYN_HIGH_QUALITY, 39742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung }; 39842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 39942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // in this test we assume a maximum transition band between 12kHz and 20kHz. 40042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 40142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 40242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<float, float>( 40342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 8, 48000, 32000, 12000, 20000, kQualityArray[i]); 40442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung } 40542b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 40642b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // in this test we assume a maximum transition band between 7kHz and 15kHz. 40742b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // there must be at least 60dB relative attenuation between stopband and passband. 40842b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung // (the weird ratio triggers interpolative resampling) 40942b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung for (size_t i = 0; i < ARRAY_SIZE(kQualityArray); ++i) { 41042b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung testStopbandDownconversion<float, float>( 41142b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 8, 48000, 22101, 7000, 15000, kQualityArray[i]); 41242b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung } 41342b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung} 41442b011166ece30969667e0ff9dcf4832568c9c1aAndy Hung 415