1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // MSVC++ requires this to be set before any other includes to get M_SQRT1_2.
6 #define _USE_MATH_DEFINES
8 #include "media/base/channel_mixing_matrix.h"
12 #include "base/strings/stringprintf.h"
13 #include "testing/gtest/include/gtest/gtest.h"
17 // Test all possible layout conversions can be constructed and mixed.
18 TEST(ChannelMixingMatrixTest
, ConstructAllPossibleLayouts
) {
19 for (ChannelLayout input_layout
= CHANNEL_LAYOUT_MONO
;
20 input_layout
<= CHANNEL_LAYOUT_MAX
;
21 input_layout
= static_cast<ChannelLayout
>(input_layout
+ 1)) {
22 for (ChannelLayout output_layout
= CHANNEL_LAYOUT_MONO
;
23 output_layout
<= CHANNEL_LAYOUT_MAX
;
24 output_layout
= static_cast<ChannelLayout
>(output_layout
+ 1)) {
25 // DISCRETE can't be tested here based on the current approach.
26 // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is not mixable.
27 // Stereo down mix should never be the output layout.
28 if (input_layout
== CHANNEL_LAYOUT_DISCRETE
||
29 input_layout
== CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
||
30 output_layout
== CHANNEL_LAYOUT_DISCRETE
||
31 output_layout
== CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
||
32 output_layout
== CHANNEL_LAYOUT_STEREO_DOWNMIX
) {
36 SCOPED_TRACE(base::StringPrintf(
37 "Input Layout: %d, Output Layout: %d", input_layout
, output_layout
));
38 ChannelMixingMatrix
matrix_builder(
40 ChannelLayoutToChannelCount(input_layout
),
42 ChannelLayoutToChannelCount(output_layout
));
43 std::vector
<std::vector
<float>> matrix
;
44 matrix_builder
.CreateTransformationMatrix(&matrix
);
49 // Verify channels are mixed and scaled correctly.
50 TEST(ChannelMixingMatrixTest
, StereoToMono
) {
51 ChannelLayout input_layout
= CHANNEL_LAYOUT_STEREO
;
52 ChannelLayout output_layout
= CHANNEL_LAYOUT_MONO
;
53 ChannelMixingMatrix
matrix_builder(
55 ChannelLayoutToChannelCount(input_layout
),
57 ChannelLayoutToChannelCount(output_layout
));
58 std::vector
<std::vector
<float>> matrix
;
59 bool remapping
= matrix_builder
.CreateTransformationMatrix(&matrix
);
63 // Output: mono CENTER 0.5 0.5
65 EXPECT_FALSE(remapping
);
66 EXPECT_EQ(1u, matrix
.size());
67 EXPECT_EQ(2u, matrix
[0].size());
68 EXPECT_EQ(0.5f
, matrix
[0][0]);
69 EXPECT_EQ(0.5f
, matrix
[0][1]);
72 TEST(ChannelMixingMatrixTest
, MonoToStereo
) {
73 ChannelLayout input_layout
= CHANNEL_LAYOUT_MONO
;
74 ChannelLayout output_layout
= CHANNEL_LAYOUT_STEREO
;
75 ChannelMixingMatrix
matrix_builder(
77 ChannelLayoutToChannelCount(input_layout
),
79 ChannelLayoutToChannelCount(output_layout
));
80 std::vector
<std::vector
<float>> matrix
;
81 bool remapping
= matrix_builder
.CreateTransformationMatrix(&matrix
);
85 // Output: stereo LEFT 1
88 EXPECT_TRUE(remapping
);
89 EXPECT_EQ(2u, matrix
.size());
90 EXPECT_EQ(1u, matrix
[0].size());
91 EXPECT_EQ(1.0f
, matrix
[0][0]);
92 EXPECT_EQ(1u, matrix
[1].size());
93 EXPECT_EQ(1.0f
, matrix
[1][0]);
96 TEST(ChannelMixingMatrixTest
, FiveOneToMono
) {
97 ChannelLayout input_layout
= CHANNEL_LAYOUT_5_1
;
98 ChannelLayout output_layout
= CHANNEL_LAYOUT_MONO
;
99 ChannelMixingMatrix
matrix_builder(
101 ChannelLayoutToChannelCount(input_layout
),
103 ChannelLayoutToChannelCount(output_layout
));
104 std::vector
<std::vector
<float>> matrix
;
105 bool remapping
= matrix_builder
.CreateTransformationMatrix(&matrix
);
107 // Note: 1/sqrt(2) is shown as 0.707.
110 // LEFT RIGHT CENTER LFE SIDE_LEFT SIDE_RIGHT
111 // Output: mono CENTER 0.707 0.707 1 0.707 0.707 0.707
113 EXPECT_FALSE(remapping
);
114 EXPECT_EQ(1u, matrix
.size());
115 EXPECT_EQ(6u, matrix
[0].size());
116 EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2
), matrix
[0][0]);
117 EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2
), matrix
[0][1]);
118 // The center channel will be mixed at scale 1.
119 EXPECT_EQ(1.0f
, matrix
[0][2]);
120 EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2
), matrix
[0][3]);
121 EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2
), matrix
[0][4]);
122 EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2
), matrix
[0][5]);
125 TEST(ChannelMixingMatrixTest
, DiscreteToDiscrete
) {
130 {2, 2}, {2, 5}, {5, 2},
133 for (size_t n
= 0; n
< arraysize(test_case
); n
++) {
134 int input_channels
= test_case
[n
].input_channels
;
135 int output_channels
= test_case
[n
].output_channels
;
136 ChannelMixingMatrix
matrix_builder(CHANNEL_LAYOUT_DISCRETE
,
138 CHANNEL_LAYOUT_DISCRETE
,
140 std::vector
<std::vector
<float>> matrix
;
141 bool remapping
= matrix_builder
.CreateTransformationMatrix(&matrix
);
142 EXPECT_TRUE(remapping
);
143 EXPECT_EQ(static_cast<size_t>(output_channels
), matrix
.size());
144 for (int i
= 0; i
< output_channels
; i
++) {
145 EXPECT_EQ(static_cast<size_t>(input_channels
), matrix
[i
].size());
146 for (int j
= 0; j
< input_channels
; j
++) {
148 EXPECT_EQ(1.0f
, matrix
[i
][j
]);
150 EXPECT_EQ(0.0f
, matrix
[i
][j
]);