330 lines
13 KiB
C++
330 lines
13 KiB
C++
/*
|
|
* Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
* A copy of the License is located at
|
|
*
|
|
* http://aws.amazon.com/apache2.0/
|
|
*
|
|
* or in the "license" file accompanying this file. This file is distributed
|
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
|
* express or implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
#include <AVSCommon/SDKInterfaces/Audio/EqualizerTypes.h>
|
|
|
|
#include "EqualizerImplementations/EqualizerLinearBandMapper.h"
|
|
|
|
namespace alexaClientSDK {
|
|
namespace equalizer {
|
|
namespace test {
|
|
|
|
using namespace ::testing;
|
|
using namespace avsCommon::sdkInterfaces::audio;
|
|
using namespace alexaClientSDK::equalizer;
|
|
|
|
/// Valid number of output bands
|
|
static constexpr int VALID_NUMBER_OF_BANDS = 3;
|
|
|
|
/// Invalid number of output bands, below lower bound
|
|
static constexpr int INVALID_NUMBER_OF_BANDS_BELOW = 0;
|
|
|
|
/// Invalid number of output bands, above higher bound
|
|
static constexpr int INVALID_NUMBER_OF_BANDS_ABOVE = 999999;
|
|
|
|
/// Band level representing high value.
|
|
static constexpr int BAND_LEVEL_TOP = 10;
|
|
/// Band level representing low value.
|
|
static constexpr int BAND_LEVEL_BOTTOM = -10;
|
|
/// Band level representing no equalization.
|
|
static constexpr int BAND_LEVEL_ZERO = 0;
|
|
|
|
/// Band level representing average of top, bottom and zero levels.
|
|
static constexpr int BAND_LEVEL_AVERAGE = (BAND_LEVEL_TOP + BAND_LEVEL_BOTTOM + BAND_LEVEL_ZERO) / 3;
|
|
|
|
/**
|
|
* Current number of AVS bands assumed in some tests. If the actual number of AVS bands changes these test would have
|
|
* to be rewritten.
|
|
*/
|
|
static constexpr int CURRENT_NUMBER_OF_AVS_BANDS = 3;
|
|
|
|
/**
|
|
* Test fixture for @c EqualizerLinearBandMapper tests
|
|
*/
|
|
class EqualizerLinearBandMapperTest : public ::testing::Test {
|
|
protected:
|
|
/**
|
|
* Helper method to test cases when all original band levels are the same and mapped levels are expected to be the
|
|
* same. This ensures the expectation that all both AVS bands and target bands cover whole frequency spectrum.
|
|
*
|
|
* @param numberOfBands Number of bands to map AVS bands to.
|
|
* @param value Band level value to be used for testing.
|
|
*/
|
|
void testAllValuesEqual(int numberOfBands, int value);
|
|
};
|
|
|
|
void EqualizerLinearBandMapperTest::testAllValuesEqual(int numberOfBands, int value) {
|
|
auto bandMapper = EqualizerLinearBandMapper::create(numberOfBands);
|
|
ASSERT_THAT(bandMapper, NotNull());
|
|
|
|
EqualizerBandLevelMap bandLevelMap;
|
|
for (auto band : EqualizerBandValues) {
|
|
bandLevelMap[band] = value;
|
|
}
|
|
|
|
std::function<void(int, int)> callback = [value](int index, int level) { EXPECT_EQ(level, value); };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
}
|
|
|
|
/// Valid parameters
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenValidParameters_create_shouldSucceed) {
|
|
auto bandMapper = EqualizerLinearBandMapper::create(VALID_NUMBER_OF_BANDS);
|
|
EXPECT_THAT(bandMapper, NotNull());
|
|
}
|
|
|
|
/// Invalid parameters
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenInvalidParameters_create_shouldFail) {
|
|
auto bandMapper = EqualizerLinearBandMapper::create(INVALID_NUMBER_OF_BANDS_BELOW);
|
|
EXPECT_THAT(bandMapper, IsNull());
|
|
|
|
bandMapper = EqualizerLinearBandMapper::create(INVALID_NUMBER_OF_BANDS_ABOVE);
|
|
EXPECT_THAT(bandMapper, IsNull());
|
|
}
|
|
|
|
/// Test mapping AVS bands to the same number of bands. No value must be modified.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenSameAsAVSBands_map_shouldNotModifyLevels) {
|
|
auto numberOfAVSBands = EqualizerBandValues.size();
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(numberOfAVSBands);
|
|
ASSERT_THAT(bandMapper, NotNull());
|
|
|
|
EqualizerBandLevelMap bandLevelMap;
|
|
int index = 0;
|
|
for (auto band : EqualizerBandValues) {
|
|
bandLevelMap[band] = index++;
|
|
}
|
|
|
|
std::function<void(int, int)> callback = [](int index, int level) { EXPECT_EQ(level, index); };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
}
|
|
|
|
/// AVS bands < target bands. Mapping non-zero value.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenMoreBandsToMapTo_mapAllSameNonZero_shouldMapToSame) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
testAllValuesEqual(numberOfAVSBands + 1, BAND_LEVEL_TOP);
|
|
}
|
|
|
|
/// AVS bands < target bands. Mapping zero value.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenMoreBandsToMapTo_mapAllSameZero_shouldMapToSame) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
testAllValuesEqual(numberOfAVSBands + 1, BAND_LEVEL_ZERO);
|
|
}
|
|
|
|
/// AVS bands * 2 = target bands. Mapping non-zero value. No averaged bands.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenDoubleBandsToMapTo_mapAllSameNonZero_shouldMapToSame) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
testAllValuesEqual(numberOfAVSBands * 2, BAND_LEVEL_TOP);
|
|
}
|
|
|
|
/// AVS bands * 2 = target bands. Mapping zero value. No averaged bands.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenDoubleBandsToMapTo_mapAllSameZero_shouldMapToSame) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
testAllValuesEqual(numberOfAVSBands * 2, BAND_LEVEL_ZERO);
|
|
}
|
|
|
|
/// AVS bands > target bands. Mapping non-zero value.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenLessBandsToMapTo_mapAllSameNonZero_shouldMapToSame) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
testAllValuesEqual(numberOfAVSBands - 1, BAND_LEVEL_TOP);
|
|
}
|
|
|
|
/// AVS bands > target bands. Mapping zero value.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenLessBandsToMapTo_mapAllSameZero_shouldMapToSame) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
testAllValuesEqual(numberOfAVSBands - 1, BAND_LEVEL_ZERO);
|
|
}
|
|
|
|
/// Mapping AVS bands to 1 target band. Non-zero value.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenOneBandToMapTo_mapNonZero_shouldMapToSame) {
|
|
testAllValuesEqual(1, BAND_LEVEL_TOP);
|
|
}
|
|
|
|
/// Mapping AVS bands to 1 target band. Zero value.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenOneBandToMapTo_mapZero_shouldMapToSame) {
|
|
testAllValuesEqual(1, BAND_LEVEL_ZERO);
|
|
}
|
|
|
|
/// Since mapper has a linear nature mapped values must keep the same average as original ones. Testing this here.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenAnyNumberOfBands_map_shouldKeepAverageLevel) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
|
|
for (int targetBandsCount = 1; targetBandsCount < numberOfAVSBands * 10; targetBandsCount++) {
|
|
auto bandMapper = EqualizerLinearBandMapper::create(targetBandsCount);
|
|
ASSERT_THAT(bandMapper, NotNull());
|
|
|
|
EqualizerBandLevelMap bandLevelMap = {
|
|
{EqualizerBand::BASS, BAND_LEVEL_BOTTOM},
|
|
{EqualizerBand::MIDRANGE, BAND_LEVEL_ZERO},
|
|
{EqualizerBand::TREBLE, BAND_LEVEL_TOP},
|
|
};
|
|
|
|
int targetLevelAccumulator = 0;
|
|
|
|
std::function<void(int, int)> callback = [&targetLevelAccumulator](int index, int level) {
|
|
targetLevelAccumulator += level;
|
|
};
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(targetLevelAccumulator / targetBandsCount, BAND_LEVEL_AVERAGE);
|
|
}
|
|
}
|
|
|
|
/// Test specific transformation. This test depends on current number of bands supported by AVS.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenMoreBandsToMapTo_mapSpecificValues_shouldMapToSpecificOutput) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
ASSERT_EQ(numberOfAVSBands, CURRENT_NUMBER_OF_AVS_BANDS);
|
|
|
|
EqualizerBandLevelMap bandLevelMap = {
|
|
{EqualizerBand::BASS, BAND_LEVEL_BOTTOM},
|
|
{EqualizerBand::MIDRANGE, BAND_LEVEL_ZERO},
|
|
{EqualizerBand::TREBLE, BAND_LEVEL_TOP},
|
|
};
|
|
|
|
std::array<int, CURRENT_NUMBER_OF_AVS_BANDS + 1> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(CURRENT_NUMBER_OF_AVS_BANDS + 1);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], BAND_LEVEL_BOTTOM);
|
|
EXPECT_EQ(mappedValues[1], (BAND_LEVEL_BOTTOM + BAND_LEVEL_ZERO) / 2);
|
|
EXPECT_EQ(mappedValues[2], (BAND_LEVEL_ZERO + BAND_LEVEL_TOP) / 2);
|
|
EXPECT_EQ(mappedValues[3], BAND_LEVEL_TOP);
|
|
}
|
|
|
|
/// Test specific transformation. This test depends on current number of bands supported by AVS.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenEvenMoreBandsToMapTo_mapSpecificValues_shouldMapToSpecificOutput) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
ASSERT_EQ(numberOfAVSBands, CURRENT_NUMBER_OF_AVS_BANDS);
|
|
|
|
EqualizerBandLevelMap bandLevelMap = {
|
|
{EqualizerBand::BASS, BAND_LEVEL_BOTTOM},
|
|
{EqualizerBand::MIDRANGE, BAND_LEVEL_ZERO},
|
|
{EqualizerBand::TREBLE, BAND_LEVEL_TOP},
|
|
};
|
|
|
|
std::array<int, CURRENT_NUMBER_OF_AVS_BANDS + 2> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(CURRENT_NUMBER_OF_AVS_BANDS + 2);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], BAND_LEVEL_BOTTOM);
|
|
EXPECT_EQ(mappedValues[1], (BAND_LEVEL_BOTTOM + BAND_LEVEL_ZERO) / 2);
|
|
EXPECT_EQ(mappedValues[2], BAND_LEVEL_ZERO);
|
|
EXPECT_EQ(mappedValues[3], (BAND_LEVEL_ZERO + BAND_LEVEL_TOP) / 2);
|
|
EXPECT_EQ(mappedValues[4], BAND_LEVEL_TOP);
|
|
}
|
|
|
|
/// Test specific transformation. This test depends on current number of bands supported by AVS.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenLessBandsToMapTo_mapSpecificValues_shouldMapToSpecificOutput) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
ASSERT_EQ(numberOfAVSBands, CURRENT_NUMBER_OF_AVS_BANDS);
|
|
|
|
EqualizerBandLevelMap bandLevelMap = {
|
|
{EqualizerBand::BASS, BAND_LEVEL_BOTTOM},
|
|
{EqualizerBand::MIDRANGE, BAND_LEVEL_ZERO},
|
|
{EqualizerBand::TREBLE, BAND_LEVEL_TOP},
|
|
};
|
|
|
|
std::array<int, CURRENT_NUMBER_OF_AVS_BANDS - 1> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(CURRENT_NUMBER_OF_AVS_BANDS - 1);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], (BAND_LEVEL_BOTTOM + BAND_LEVEL_ZERO) / 2);
|
|
EXPECT_EQ(mappedValues[1], (BAND_LEVEL_TOP + BAND_LEVEL_ZERO) / 2);
|
|
}
|
|
|
|
/// Test specific transformation. This test depends on current number of bands supported by AVS.
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenEvenLessBandsToMapTo_mapSpecificValues_shouldMapToSpecificOutput) {
|
|
int numberOfAVSBands = EqualizerBandValues.size();
|
|
ASSERT_EQ(numberOfAVSBands, CURRENT_NUMBER_OF_AVS_BANDS);
|
|
|
|
EqualizerBandLevelMap bandLevelMap = {
|
|
{EqualizerBand::BASS, BAND_LEVEL_BOTTOM},
|
|
{EqualizerBand::MIDRANGE, BAND_LEVEL_ZERO},
|
|
{EqualizerBand::TREBLE, BAND_LEVEL_TOP},
|
|
};
|
|
|
|
std::array<int, CURRENT_NUMBER_OF_AVS_BANDS - 2> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(CURRENT_NUMBER_OF_AVS_BANDS - 2);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], (BAND_LEVEL_BOTTOM + BAND_LEVEL_ZERO + BAND_LEVEL_TOP) / 3);
|
|
}
|
|
|
|
///
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenOneBandSupported_mapToOneBand_shouldMapSameValue) {
|
|
EqualizerBandLevelMap bandLevelMap = {{EqualizerBand::BASS, BAND_LEVEL_BOTTOM}};
|
|
|
|
std::array<int, 1> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(1);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], BAND_LEVEL_BOTTOM);
|
|
}
|
|
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenOneBandSupported_mapToTwoBands_shouldMapToBothSame) {
|
|
EqualizerBandLevelMap bandLevelMap = {{EqualizerBand::BASS, BAND_LEVEL_BOTTOM}};
|
|
|
|
std::array<int, 2> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(2);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], BAND_LEVEL_BOTTOM);
|
|
EXPECT_EQ(mappedValues[1], BAND_LEVEL_BOTTOM);
|
|
}
|
|
|
|
TEST_F(EqualizerLinearBandMapperTest, test_givenTwoBandsSupported_mapToOneBands_shouldMapToAverage) {
|
|
EqualizerBandLevelMap bandLevelMap = {{EqualizerBand::BASS, BAND_LEVEL_BOTTOM},
|
|
{EqualizerBand::MIDRANGE, BAND_LEVEL_ZERO}};
|
|
|
|
std::array<int, 1> mappedValues{};
|
|
|
|
auto bandMapper = EqualizerLinearBandMapper::create(1);
|
|
std::function<void(int, int)> callback = [&mappedValues](int index, int level) { mappedValues[index] = level; };
|
|
|
|
bandMapper->mapEqualizerBands(bandLevelMap, callback);
|
|
|
|
EXPECT_EQ(mappedValues[0], (BAND_LEVEL_BOTTOM + BAND_LEVEL_ZERO) / 2);
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace equalizer
|
|
} // namespace alexaClientSDK
|