Chromium Code Reviews| Index: media/base/channel_mixing_matrix_unittest.cc |
| diff --git a/media/base/channel_mixing_matrix_unittest.cc b/media/base/channel_mixing_matrix_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7feab60077f0f1833feceb6af5ed7006094a5408 |
| --- /dev/null |
| +++ b/media/base/channel_mixing_matrix_unittest.cc |
| @@ -0,0 +1,156 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// MSVC++ requires this to be set before any other includes to get M_SQRT1_2. |
| +#define _USE_MATH_DEFINES |
| + |
| +#include "media/base/channel_mixing_matrix.h" |
| + |
| +#include <cmath> |
| + |
| +#include "base/strings/stringprintf.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace media { |
| + |
| +// Test all possible layout conversions can be constructed and mixed. |
| +TEST(ChannelMixingMatrixTest, ConstructAllPossibleLayouts) { |
| + for (ChannelLayout input_layout = CHANNEL_LAYOUT_MONO; |
| + input_layout <= CHANNEL_LAYOUT_MAX; |
| + input_layout = static_cast<ChannelLayout>(input_layout + 1)) { |
| + for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO; |
| + // TODO(wtc): why do we only test up to CHANNEL_LAYOUT_STEREO_DOWNMIX? |
| + output_layout < CHANNEL_LAYOUT_STEREO_DOWNMIX; |
| + output_layout = static_cast<ChannelLayout>(output_layout + 1)) { |
| + // DISCRETE can't be tested here based on the current approach. |
| + // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is not mixable. |
| + if (input_layout == CHANNEL_LAYOUT_DISCRETE || |
| + input_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC || |
| + output_layout == CHANNEL_LAYOUT_DISCRETE || |
| + output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { |
| + continue; |
| + } |
| + |
| + SCOPED_TRACE(base::StringPrintf( |
| + "Input Layout: %d, Output Layout: %d", input_layout, output_layout)); |
| + ChannelMixingMatrix matrix_builder( |
| + input_layout, |
| + ChannelLayoutToChannelCount(input_layout), |
| + output_layout, |
| + ChannelLayoutToChannelCount(output_layout)); |
| + std::vector<std::vector<float>> matrix; |
| + matrix_builder.CreateTransformationMatrix(&matrix); |
| + } |
| + } |
| +} |
| + |
| +// Verify channels are mixed and scaled correctly. |
| +TEST(ChannelMixingMatrixTest, StereoToMono) { |
| + ChannelLayout input_layout = CHANNEL_LAYOUT_STEREO; |
| + ChannelLayout output_layout = CHANNEL_LAYOUT_MONO; |
| + ChannelMixingMatrix matrix_builder( |
| + input_layout, |
| + ChannelLayoutToChannelCount(input_layout), |
| + output_layout, |
| + ChannelLayoutToChannelCount(output_layout)); |
| + std::vector<std::vector<float>> matrix; |
| + bool remapping = matrix_builder.CreateTransformationMatrix(&matrix); |
| + |
| + // Input: stereo |
| + // LEFT RIGHT |
| + // Output: mono CENTER 0.5 0.5 |
| + // |
| + EXPECT_FALSE(remapping); |
| + EXPECT_EQ(1u, matrix.size()); |
| + EXPECT_EQ(2u, matrix[0].size()); |
| + EXPECT_EQ(0.5f, matrix[0][0]); |
| + EXPECT_EQ(0.5f, matrix[0][1]); |
| +} |
| + |
| +TEST(ChannelMixingMatrixTest, MonoToStereo) { |
| + ChannelLayout input_layout = CHANNEL_LAYOUT_MONO; |
| + ChannelLayout output_layout = CHANNEL_LAYOUT_STEREO; |
| + ChannelMixingMatrix matrix_builder( |
| + input_layout, |
| + ChannelLayoutToChannelCount(input_layout), |
| + output_layout, |
| + ChannelLayoutToChannelCount(output_layout)); |
| + std::vector<std::vector<float>> matrix; |
| + bool remapping = matrix_builder.CreateTransformationMatrix(&matrix); |
| + |
| + // Input: mono |
| + // CENTER |
| + // Output: stereo LEFT 1 |
| + // RIGHT 1 |
| + // |
| + EXPECT_TRUE(remapping); |
| + EXPECT_EQ(2u, matrix.size()); |
| + EXPECT_EQ(1u, matrix[0].size()); |
| + EXPECT_EQ(1.0f, matrix[0][0]); |
| + EXPECT_EQ(1u, matrix[1].size()); |
| + EXPECT_EQ(1.0f, matrix[1][0]); |
| +} |
| + |
| +TEST(ChannelMixingMatrixTest, FiveOneToMono) { |
| + ChannelLayout input_layout = CHANNEL_LAYOUT_5_1; |
| + ChannelLayout output_layout = CHANNEL_LAYOUT_MONO; |
| + ChannelMixingMatrix matrix_builder( |
| + input_layout, |
| + ChannelLayoutToChannelCount(input_layout), |
| + output_layout, |
| + ChannelLayoutToChannelCount(output_layout)); |
| + std::vector<std::vector<float>> matrix; |
| + bool remapping = matrix_builder.CreateTransformationMatrix(&matrix); |
| + |
| + // Note: 1/sqrt(2) is shown as 0.707. |
| + // |
| + // Input: 5.1 |
| + // LEFT RIGHT CENTER LFE SIDE_LEFT SIDE_RIGHT |
| + // Output: mono CENTER 0.707 0.707 1 0.707 0.707 0.707 |
|
wtc
2014/10/23 16:55:13
Dale: I added graphical representations of the mat
DaleCurtis
2014/10/23 17:15:27
By all means, please analyze :) I intuitively chos
wtc
2014/10/23 18:39:45
That's a good rationale and it's supported by your
|
| + // |
| + EXPECT_FALSE(remapping); |
| + EXPECT_EQ(1u, matrix.size()); |
| + EXPECT_EQ(6u, matrix[0].size()); |
| + EXPECT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][0]); |
| + EXPECT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][1]); |
| + // The center channel will be mixed at scale 1. |
| + EXPECT_EQ(1.0f, matrix[0][2]); |
| + EXPECT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][3]); |
| + EXPECT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][4]); |
| + EXPECT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][5]); |
| +} |
| + |
| +TEST(ChannelMixingMatrixTest, DiscreteToDiscrete) { |
| + const struct { |
| + int input_channels; |
| + int output_channels; |
| + } test_case[] = { |
| + {2, 2}, {2, 5}, {5, 2}, |
| + }; |
| + |
| + for (size_t n = 0; n < arraysize(test_case); n++) { |
| + int input_channels = test_case[n].input_channels; |
| + int output_channels = test_case[n].output_channels; |
| + ChannelMixingMatrix matrix_builder(CHANNEL_LAYOUT_DISCRETE, |
| + input_channels, |
| + CHANNEL_LAYOUT_DISCRETE, |
| + output_channels); |
| + std::vector<std::vector<float>> matrix; |
| + bool remapping = matrix_builder.CreateTransformationMatrix(&matrix); |
| + EXPECT_TRUE(remapping); |
| + EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size()); |
| + for (int i = 0; i < output_channels; i++) { |
| + EXPECT_EQ(static_cast<size_t>(input_channels), matrix[i].size()); |
| + for (int j = 0; j < input_channels; j++) { |
| + if (i == j) { |
| + EXPECT_EQ(1.0f, matrix[i][j]); |
| + } else { |
| + EXPECT_EQ(0.0f, matrix[i][j]); |
| + } |
| + } |
| + } |
| + } |
| +} |
| + |
| +} // namespace media |