Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3b04002 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "VtsHalTargetTest: Configure channel layout and generate input data correctly" into main

parents 95406bff fbb5cd32
Loading
Loading
Loading
Loading
+97 −25
Original line number Diff line number Diff line
@@ -85,7 +85,9 @@ static inline std::string getPrefix(Descriptor& descriptor) {
}

static constexpr float kMaxAudioSampleValue = 1;
static constexpr int kNPointFFT = 16384;
static constexpr int kSamplingFrequency = 44100;
static constexpr int kDefaultChannelLayout = AudioChannelLayout::LAYOUT_STEREO;

class EffectHelper {
  public:
@@ -259,13 +261,14 @@ class EffectHelper {
        EXPECT_TRUE(efState & kEventFlagDataMqUpdate);
    }

    Parameter::Common createParamCommon(int session = 0, int ioHandle = -1, int iSampleRate = 48000,
                                        int oSampleRate = 48000, long iFrameCount = 0x100,
                                        long oFrameCount = 0x100) {
        AudioChannelLayout inputLayout = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
                AudioChannelLayout::LAYOUT_STEREO);
        AudioChannelLayout outputLayout = inputLayout;

    Parameter::Common createParamCommon(
            int session = 0, int ioHandle = -1, int iSampleRate = 48000, int oSampleRate = 48000,
            long iFrameCount = 0x100, long oFrameCount = 0x100,
            AudioChannelLayout inputChannelLayout =
                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(kDefaultChannelLayout),
            AudioChannelLayout outputChannelLayout =
                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
                            kDefaultChannelLayout)) {
        // query supported input layout and use it as the default parameter in common
        if (mIsSpatializer && isRangeValid<Range::spatializer>(Spatializer::supportedChannelLayout,
                                                               mDescriptor.capability)) {
@@ -275,18 +278,10 @@ class EffectHelper {
                layoutRange &&
                0 != (layouts = layoutRange->min.get<Spatializer::supportedChannelLayout>())
                                .size()) {
                inputLayout = layouts[0];
            }
                inputChannelLayout = layouts[0];
            }

        return createParamCommon(session, ioHandle, iSampleRate, oSampleRate, iFrameCount,
                                 oFrameCount, inputLayout, outputLayout);
        }

    static Parameter::Common createParamCommon(int session, int ioHandle, int iSampleRate,
                                               int oSampleRate, long iFrameCount, long oFrameCount,
                                               AudioChannelLayout inputChannelLayout,
                                               AudioChannelLayout outputChannelLayout) {
        Parameter::Common common;
        common.session = session;
        common.ioHandle = ioHandle;
@@ -463,43 +458,120 @@ class EffectHelper {

    // Generate multitone input between -amplitude to +amplitude using testFrequencies
    // All test frequencies are considered having the same amplitude
    // The function supports only mono and stereo channel layout
    void generateSineWave(const std::vector<int>& testFrequencies, std::vector<float>& input,
                          const float amplitude = 1.0,
                          const int samplingFrequency = kSamplingFrequency) {
        for (size_t i = 0; i < input.size(); i++) {
                          const int samplingFrequency = kSamplingFrequency,
                          int channelLayout = AudioChannelLayout::LAYOUT_STEREO) {
        bool isStereo = (channelLayout == AudioChannelLayout::LAYOUT_STEREO);
        if (isStereo) {
            ASSERT_EQ(input.size() % 2, 0u)
                    << "In case of stereo input, the input size value must be even";
        }
        for (size_t i = 0; i < input.size(); i += (isStereo ? 2 : 1)) {
            input[i] = 0;

            for (size_t j = 0; j < testFrequencies.size(); j++) {
                input[i] += sin(2 * M_PI * testFrequencies[j] * i / samplingFrequency);
                input[i] += sin(2 * M_PI * testFrequencies[j] * (i / (isStereo ? 2 : 1)) /
                                samplingFrequency);
            }
            input[i] *= amplitude / testFrequencies.size();

            if (isStereo) {
                input[i + 1] = input[i];
            }
        }
    }

    // Generate single tone input between -amplitude to +amplitude using testFrequency
    // The function supports only mono and stereo channel layout
    void generateSineWave(const int testFrequency, std::vector<float>& input,
                          const float amplitude = 1.0,
                          const int samplingFrequency = kSamplingFrequency) {
        generateSineWave(std::vector<int>{testFrequency}, input, amplitude, samplingFrequency);
                          const int samplingFrequency = kSamplingFrequency,
                          int channelLayout = AudioChannelLayout::LAYOUT_STEREO) {
        ASSERT_NO_FATAL_FAILURE(generateSineWave(std::vector<int>{testFrequency}, input, amplitude,
                                                 samplingFrequency, channelLayout));
    }

    // PFFFT only supports transforms for inputs of length N of the form N = (2^a)*(3^b)*(5^c) where
    // a >= 5, b >=0, c >= 0.
    constexpr bool isFftInputSizeValid(size_t n) {
        if (n == 0 || n & 0b11111) {
            return false;
        }
        for (const int factor : {2, 3, 5}) {
            while (n % factor == 0) {
                n /= factor;
            }
        }
        return n == 1;
    }

    // Use FFT transform to convert the buffer to frequency domain
    // Compute its magnitude at binOffsets
    std::vector<float> calculateMagnitude(const std::vector<float>& buffer,
                                          const std::vector<int>& binOffsets, const int nPointFFT) {
    void calculateMagnitudeMono(std::vector<float>& bufferMag,       // Output parameter
                                const std::vector<float>& buffer,    // Input parameter
                                const std::vector<int>& binOffsets,  // Input parameter
                                const int nPointFFT = kNPointFFT) {  // Input parameter
        ASSERT_TRUE(isFftInputSizeValid(nPointFFT))
                << "PFFFT only supports transforms for inputs of length N of the form N = (2 ^ a) "
                   "* (3 ^ b) * (5 ^ c) where a >= 5, b >= 0, c >= 0. ";
        ASSERT_GE((int)buffer.size(), nPointFFT)
                << "The input(buffer) size must be greater than or equal to nPointFFT";
        bufferMag.resize(binOffsets.size());
        std::vector<float> fftInput(nPointFFT);
        PFFFT_Setup* inputHandle = pffft_new_setup(nPointFFT, PFFFT_REAL);
        pffft_transform_ordered(inputHandle, buffer.data(), fftInput.data(), nullptr,
                                PFFFT_FORWARD);
        pffft_destroy_setup(inputHandle);
        std::vector<float> bufferMag(binOffsets.size());
        for (size_t i = 0; i < binOffsets.size(); i++) {
            size_t k = binOffsets[i];
            bufferMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
                                (fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
        }
    }

        return bufferMag;
    // Use FFT transform to convert the buffer to frequency domain
    // Compute its magnitude at binOffsets
    void calculateMagnitudeStereo(
            std::pair<std::vector<float>, std::vector<float>>& bufferMag,  // Output parameter
            const std::vector<float>& buffer,                              // Input parameter
            const std::vector<int>& binOffsets,                            // Input parameter
            const int nPointFFT = kNPointFFT) {                            // Input parameter
        std::vector<float> leftChannelBuffer(buffer.size() / 2),
                rightChannelBuffer(buffer.size() / 2);
        for (size_t i = 0; i < buffer.size(); i += 2) {
            leftChannelBuffer[i / 2] = buffer[i];
            rightChannelBuffer[i / 2] = buffer[i + 1];
        }
        std::vector<float> leftMagnitude(binOffsets.size());
        std::vector<float> rightMagnitude(binOffsets.size());

        ASSERT_NO_FATAL_FAILURE(
                calculateMagnitudeMono(leftMagnitude, leftChannelBuffer, binOffsets, nPointFFT));
        ASSERT_NO_FATAL_FAILURE(
                calculateMagnitudeMono(rightMagnitude, rightChannelBuffer, binOffsets, nPointFFT));

        bufferMag = {leftMagnitude, rightMagnitude};
    }

    // Computes magnitude for mono and stereo inputs and verifies equal magnitude for left and right
    // channel in case of stereo inputs
    void calculateAndVerifyMagnitude(std::vector<float>& mag,             // Output parameter
                                     const int channelLayout,             // Input parameter
                                     const std::vector<float>& buffer,    // Input parameter
                                     const std::vector<int>& binOffsets,  // Input parameter
                                     const int nPointFFT = kNPointFFT) {  // Input parameter
        if (channelLayout == AudioChannelLayout::LAYOUT_STEREO) {
            std::pair<std::vector<float>, std::vector<float>> magStereo;
            ASSERT_NO_FATAL_FAILURE(
                    calculateMagnitudeStereo(magStereo, buffer, binOffsets, nPointFFT));
            ASSERT_EQ(magStereo.first, magStereo.second);

            mag = magStereo.first;
        } else {
            ASSERT_NO_FATAL_FAILURE(calculateMagnitudeMono(mag, buffer, binOffsets, nPointFFT));
        }
    }

    void updateFrameSize(const Parameter::Common& common) {
+13 −26
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ static const std::vector<int32_t> kLayouts = {AudioChannelLayout::LAYOUT_STEREO,

class BassBoostEffectHelper : public EffectHelper {
  public:
    void SetUpBassBoost(int32_t layout = AudioChannelLayout::LAYOUT_STEREO) {
    void SetUpBassBoost(int32_t layout = kDefaultChannelLayout) {
        ASSERT_NE(nullptr, mFactory);
        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
        setFrameCounts(layout);
@@ -113,7 +113,7 @@ class BassBoostEffectHelper : public EffectHelper {
        }
    }

    static constexpr int kDurationMilliSec = 720;
    static constexpr int kDurationMilliSec = 1440;
    static constexpr int kInputSize = kSamplingFrequency * kDurationMilliSec / 1000;
    long mInputFrameCount, mOutputFrameCount;
    std::shared_ptr<IFactory> mFactory;
@@ -187,25 +187,6 @@ class BassBoostDataTest : public ::testing::TestWithParam<BassBoostDataTestParam
        }
    }

    // Use FFT transform to convert the buffer to frequency domain
    // Compute its magnitude at binOffsets
    std::vector<float> calculateMagnitude(const std::vector<float>& buffer,
                                          const std::vector<int>& binOffsets) {
        std::vector<float> fftInput(kNPointFFT);
        PFFFT_Setup* inputHandle = pffft_new_setup(kNPointFFT, PFFFT_REAL);
        pffft_transform_ordered(inputHandle, buffer.data(), fftInput.data(), nullptr,
                                PFFFT_FORWARD);
        pffft_destroy_setup(inputHandle);
        std::vector<float> bufferMag(binOffsets.size());
        for (size_t i = 0; i < binOffsets.size(); i++) {
            size_t k = binOffsets[i];
            bufferMag[i] = sqrt((fftInput[k * 2] * fftInput[k * 2]) +
                                (fftInput[k * 2 + 1] * fftInput[k * 2 + 1]));
        }

        return bufferMag;
    }

    // Calculate gain difference between low frequency and high frequency magnitude
    float calculateGainDiff(const std::vector<float>& inputMag,
                            const std::vector<float>& outputMag) {
@@ -218,7 +199,6 @@ class BassBoostDataTest : public ::testing::TestWithParam<BassBoostDataTestParam
        return gains[0] - gains[1];
    }

    static constexpr int kNPointFFT = 16384;
    static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
    std::set<int> mStrengthValues;
    int32_t mChannelLayout;
@@ -240,9 +220,11 @@ TEST_P(BassBoostDataTest, IncreasingStrength) {
    roundToFreqCenteredToFftBin(testFrequencies, binOffsets);

    // Generate multitone input
    generateSineWave(testFrequencies, input);
    ASSERT_NO_FATAL_FAILURE(
            generateSineWave(testFrequencies, input, 1.0, kSamplingFrequency, mChannelLayout));

    inputMag = calculateMagnitude(input, binOffsets);
    ASSERT_NO_FATAL_FAILURE(
            calculateAndVerifyMagnitude(inputMag, mChannelLayout, input, binOffsets));

    if (isStrengthValid(0)) {
        ASSERT_NO_FATAL_FAILURE(setAndVerifyParameters(0, EX_NONE));
@@ -254,7 +236,10 @@ TEST_P(BassBoostDataTest, IncreasingStrength) {
            processAndWriteToOutput(input, baseOutput, mEffect, &mOpenEffectReturn));

    std::vector<float> baseMag(testFrequencies.size());
    baseMag = calculateMagnitude(baseOutput, binOffsets);

    ASSERT_NO_FATAL_FAILURE(
            calculateAndVerifyMagnitude(baseMag, mChannelLayout, baseOutput, binOffsets));

    float baseDiff = calculateGainDiff(inputMag, baseMag);

    for (int strength : mStrengthValues) {
@@ -271,7 +256,9 @@ TEST_P(BassBoostDataTest, IncreasingStrength) {
        ASSERT_NO_FATAL_FAILURE(
                processAndWriteToOutput(input, output, mEffect, &mOpenEffectReturn));

        outputMag = calculateMagnitude(output, binOffsets);
        ASSERT_NO_FATAL_FAILURE(
                calculateAndVerifyMagnitude(outputMag, mChannelLayout, output, binOffsets));

        float diff = calculateGainDiff(inputMag, outputMag);

        ASSERT_GT(diff, prevGain);
+1 −1
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ static const std::vector<int32_t> kChannels = {

class DownmixEffectHelper : public EffectHelper {
  public:
    void SetUpDownmix(int32_t inputBufferLayout = AudioChannelLayout::LAYOUT_STEREO) {
    void SetUpDownmix(int32_t inputBufferLayout = kDefaultChannelLayout) {
        ASSERT_NE(nullptr, mFactory);
        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));

+12 −7
Original line number Diff line number Diff line
@@ -46,8 +46,8 @@ using android::hardware::audio::common::testing::detail::TestExecutionTracer;
class DynamicsProcessingTestHelper : public EffectHelper {
  public:
    DynamicsProcessingTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair,
                                 int32_t channelLayOut = AudioChannelLayout::LAYOUT_STEREO)
        : mChannelLayout(channelLayOut),
                                 int32_t channelLayout = kDefaultChannelLayout)
        : mChannelLayout(channelLayout),
          mChannelCount(::aidl::android::hardware::audio::common::getChannelCount(
                  AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout))) {
        std::tie(mFactory, mDescriptor) = pair;
@@ -162,11 +162,12 @@ class DynamicsProcessingTestHelper : public EffectHelper {
    static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;

  private:
    const int32_t mChannelLayout;
    std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;

  protected:
    const int32_t mChannelLayout;
    const int mChannelCount;

    void CleanUp() {
        mTags.clear();
        mPreEqChannelEnable.clear();
@@ -397,6 +398,8 @@ bool DynamicsProcessingTestHelper::isAllParamsValid() {
    return true;
}

// This function calculates power for both and mono and stereo data as the total power for
// interleaved multichannel data can be calculated by treating it as a continuous mono input.
float DynamicsProcessingTestHelper::calculateDb(const std::vector<float>& input,
                                                size_t startSamplePos = 0) {
    return audio_utils_compute_power_mono(input.data() + startSamplePos, AUDIO_FORMAT_PCM_FLOAT,
@@ -623,13 +626,14 @@ class DynamicsProcessingInputGainDataTest
    DynamicsProcessingInputGainDataTest()
        : DynamicsProcessingTestHelper((GetParam()), AudioChannelLayout::LAYOUT_MONO) {
        mInput.resize(kFrameCount * mChannelCount);
        generateSineWave(kInputFrequency /*Input Frequency*/, mInput);
        mInputDb = calculateDb(mInput);
    }

    void SetUp() override {
        SetUpDynamicsProcessingEffect();
        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
        ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency /*Input Frequency*/, mInput, 1.0,
                                                 kSamplingFrequency, mChannelLayout));
        mInputDb = calculateDb(mInput);
    }

    void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -758,13 +762,14 @@ class DynamicsProcessingLimiterConfigDataTest
        : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
        mBufferSize = kFrameCount * mChannelCount;
        mInput.resize(mBufferSize);
        generateSineWave(1000 /*Input Frequency*/, mInput);
        mInputDb = calculateDb(mInput);
    }

    void SetUp() override {
        SetUpDynamicsProcessingEffect();
        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
        ASSERT_NO_FATAL_FAILURE(generateSineWave(1000 /*Input Frequency*/, mInput, 1.0,
                                                 kSamplingFrequency, mChannelLayout));
        mInputDb = calculateDb(mInput);
    }

    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+15 −10
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ static std::vector<TagValuePair> buildSetAndGetTestParams() {

    return valueTag;
}

/**
 * Tests do the following:
 * - Testing parameter range supported by the effect. Range is verified with IEffect.getDescriptor()
@@ -282,10 +283,10 @@ class EnvironmentalReverbHelper : public EffectHelper {
    static constexpr int kDurationMilliSec = 500;
    static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
    static constexpr int kInputFrequency = 2000;
    static constexpr int mChannelLayout = AudioChannelLayout::LAYOUT_STEREO;

    int mStereoChannelCount =
            getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
                    AudioChannelLayout::LAYOUT_STEREO));
    int mStereoChannelCount = getChannelCount(
            AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
    int mFrameCount = kBufferSize / mStereoChannelCount;

    std::shared_ptr<IFactory> mFactory;
@@ -344,10 +345,11 @@ class EnvironmentalReverbDataTest
        : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
        std::tie(mTag, mParamValues) = std::get<TAG_VALUE_PAIR>(GetParam());
        mInput.resize(kBufferSize);
        generateSineWave(kInputFrequency, mInput);
    }
    void SetUp() override {
        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
        ASSERT_NO_FATAL_FAILURE(
                generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
        SetUpReverb();
    }
    void TearDown() override {
@@ -434,7 +436,8 @@ class EnvironmentalReverbMinimumParamTest

TEST_P(EnvironmentalReverbMinimumParamTest, MinimumValueTest) {
    std::vector<float> input(kBufferSize);
    generateSineWave(kInputFrequency, input);
    ASSERT_NO_FATAL_FAILURE(
            generateSineWave(kInputFrequency, input, 1.0, kSamplingFrequency, mChannelLayout));
    std::vector<float> output(kBufferSize);
    setParameterAndProcess(input, output, mValue, mTag);
    float energy = computeOutputEnergy(input, output);
@@ -470,10 +473,11 @@ class EnvironmentalReverbDiffusionTest
        : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
        std::tie(mTag, mParamValues) = std::get<TAG_VALUE_PAIR>(GetParam());
        mInput.resize(kBufferSize);
        generateSineWave(kInputFrequency, mInput);
    }
    void SetUp() override {
        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
        ASSERT_NO_FATAL_FAILURE(
                generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
        SetUpReverb();
    }
    void TearDown() override {
@@ -546,14 +550,15 @@ class EnvironmentalReverbDensityTest
        mParamValues = std::get<PARAM_DENSITY_VALUE>(GetParam());
        mIsInputMute = (std::get<IS_INPUT_MUTE>(GetParam()));
        mInput.resize(kBufferSize);
    }
    void SetUp() override {
        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
        if (mIsInputMute) {
            std::fill(mInput.begin(), mInput.end(), 0);
        } else {
            generateSineWave(kInputFrequency, mInput);
        }
            ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency, mInput, 1.0,
                                                     kSamplingFrequency, mChannelLayout));
        }
    void SetUp() override {
        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
        SetUpReverb();
    }
    void TearDown() override {
Loading