blob: 207cf469f077dfb00792bcf1e7e81d27ce2ed342 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/lib/format2/channel_mapper.h"
#include <cstdint>
#include <vector>
#include <gtest/gtest.h>
#include "src/media/audio/lib/format2/sample_converter.h"
namespace media_audio {
namespace {
TEST(ChannelMapperTest, SameChannels) {
ChannelMapper<int16_t, 4, 4> mapper;
const std::vector<int16_t> input = {-0x4000, kMinInt16, 0, 0x4000};
const std::vector<float> expected = {-0.5f, -1.0f, 0.0f, 0.5f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
TEST(ChannelMapperTest, MonoToStereo) {
ChannelMapper<int16_t, 1, 2> mapper;
const int16_t input = 0x4000; // 0.5f
for (size_t channel = 0; channel < 2; ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(&input, 0), 0.5f);
}
}
TEST(ChannelMapperTest, MonoToThreeChannels) {
ChannelMapper<uint8_t, 1, 3> mapper;
const uint8_t input = 0x40; // -0.5f
for (size_t channel = 0; channel < 3; ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(&input, 0), -0.5f);
}
}
TEST(ChannelMapperTest, MonoToFourChannels) {
ChannelMapper<float, 1, 4> mapper;
const float input = 0.2f;
for (size_t channel = 0; channel < 4; ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(&input, 0), 0.2f);
}
}
TEST(ChannelMapperTest, StereoToMono) {
ChannelMapper<int16_t, 2, 1> mapper;
const std::vector<int16_t> input = {-0x2000, -0x4000}; // {-0.25f, -0.5f}
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), -0.375f);
}
TEST(ChannelMapperTest, StereoToThreeChannels) {
ChannelMapper<float, 2, 3> mapper;
const std::vector<float> input = {-0.25f, 0.75f};
const std::vector<float> expected = {-0.25f, 0.75f, 0.25f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
TEST(ChannelMapperTest, StereoToFourChannels) {
ChannelMapper<float, 2, 4> mapper;
const std::vector<float> input = {-0.25f, 0.75f};
const std::vector<float> expected = {-0.25f, 0.75f, -0.25f, 0.75f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
TEST(ChannelMapperTest, ThreeChannelsToMono) {
ChannelMapper<float, 3, 1> mapper;
const std::vector<float> input = {-1.0f, 0.5f, -0.1f};
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), -0.2f);
}
TEST(ChannelMapperTest, ThreeChannelsToStereo) {
ChannelMapper<float, 3, 2> mapper;
const std::vector<float> input = {1.0f, -0.5f, -0.5f};
const std::vector<float> expected = {0.378679656f, -0.5f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
TEST(ChannelMapperTest, FourChannelsToMono) {
ChannelMapper<float, 4, 1> mapper;
const std::vector<float> input = {1.0f, 2.0f, 3.0f, 4.0f};
if constexpr (kEnable4ChannelWorkaround) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 1.5f);
} else {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 5.0f);
}
}
TEST(ChannelMapperTest, FourChannelsToStereo) {
ChannelMapper<float, 4, 2> mapper;
const std::vector<float> input = {1.0f, 2.0f, 3.0f, 4.0f};
if constexpr (kEnable4ChannelWorkaround) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 1.0f);
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 1), 2.0f);
} else {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 1.5f);
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 1), 3.0f);
}
}
TEST(ChannelMapperTest, CustomizableSameChannels) {
ChannelMapper<float, 2, 2, /*Customizable=*/true> mapper({{
{-1.0f, 0.0f},
{0.5f, 0.5f},
}});
const std::vector<float> input = {2.0f, 3.0f};
const std::vector<float> expected = {-2.0f, 2.5f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
TEST(ChannelMapperTest, CustomizableSingleToMulti) {
ChannelMapper<float, 1, 3, /*Customizable=*/true> mapper({{{1.0f}, {-2.0f}, {3.0f}}});
const std::vector<float> input = {0.5f};
const std::vector<float> expected = {0.5f, -1.0f, 1.5f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
TEST(ChannelMapperTest, CustomizableMultiToSingle) {
ChannelMapper<float, 2, 1, /*Customizable=*/true> mapper({{{1.0f, 0.25f}}});
const std::vector<float> input = {2.0f, 4.0f};
EXPECT_FLOAT_EQ(mapper.Map(input.data(), 0), 3.0f);
}
TEST(ChannelMapperTest, CustomizableMultiToMulti) {
ChannelMapper<float, 3, 5, /*Customizable=*/true> mapper({{
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 1.0f},
{-1.0f, 2.0f, -3.0f},
}});
const std::vector<float> input = {1.0f, 2.0f, 3.0f};
const std::vector<float> expected = {1.0f, 2.0f, 3.0f, 6.0f, -6.0f};
for (size_t channel = 0; channel < expected.size(); ++channel) {
EXPECT_FLOAT_EQ(mapper.Map(input.data(), channel), expected[channel]);
}
}
} // namespace
} // namespace media_audio