Loading audio/aidl/vts/EffectHelper.h +97 −25 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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)) { Loading @@ -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; Loading Loading @@ -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) { Loading audio/aidl/vts/VtsHalBassBoostTargetTest.cpp +13 −26 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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)); Loading @@ -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) { Loading @@ -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); Loading audio/aidl/vts/VtsHalDownmixTargetTest.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp +12 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading @@ -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(); } Loading Loading @@ -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(); } Loading audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp +15 −10 Original line number Diff line number Diff line Loading @@ -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() Loading Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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); Loading Loading @@ -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 { Loading Loading @@ -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 Loading
audio/aidl/vts/EffectHelper.h +97 −25 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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)) { Loading @@ -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; Loading Loading @@ -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) { Loading
audio/aidl/vts/VtsHalBassBoostTargetTest.cpp +13 −26 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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)); Loading @@ -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) { Loading @@ -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); Loading
audio/aidl/vts/VtsHalDownmixTargetTest.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading
audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp +12 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading @@ -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(); } Loading Loading @@ -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(); } Loading
audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp +15 −10 Original line number Diff line number Diff line Loading @@ -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() Loading Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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); Loading Loading @@ -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 { Loading Loading @@ -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