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