channel_mixing_matrix_unittest.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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.
  4. #include "media/base/channel_mixing_matrix.h"
  5. #include <stddef.h>
  6. #include "base/strings/stringprintf.h"
  7. #include "media/base/channel_mixer.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace media {
  10. // Test all possible layout conversions can be constructed and mixed.
  11. TEST(ChannelMixingMatrixTest, ConstructAllPossibleLayouts) {
  12. for (ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
  13. input_layout <= CHANNEL_LAYOUT_MAX;
  14. input_layout = static_cast<ChannelLayout>(input_layout + 1)) {
  15. for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
  16. output_layout <= CHANNEL_LAYOUT_MAX;
  17. output_layout = static_cast<ChannelLayout>(output_layout + 1)) {
  18. // DISCRETE, BITSTREAM can't be tested here based on the current approach.
  19. // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is deprecated.
  20. // Stereo down mix should never be the output layout.
  21. if (input_layout == CHANNEL_LAYOUT_BITSTREAM ||
  22. input_layout == CHANNEL_LAYOUT_DISCRETE ||
  23. input_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
  24. output_layout == CHANNEL_LAYOUT_BITSTREAM ||
  25. output_layout == CHANNEL_LAYOUT_DISCRETE ||
  26. output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
  27. output_layout == CHANNEL_LAYOUT_STEREO_DOWNMIX) {
  28. continue;
  29. }
  30. SCOPED_TRACE(base::StringPrintf(
  31. "Input Layout: %d, Output Layout: %d", input_layout, output_layout));
  32. ChannelMixingMatrix matrix_builder(
  33. input_layout,
  34. ChannelLayoutToChannelCount(input_layout),
  35. output_layout,
  36. ChannelLayoutToChannelCount(output_layout));
  37. std::vector<std::vector<float>> matrix;
  38. matrix_builder.CreateTransformationMatrix(&matrix);
  39. }
  40. }
  41. }
  42. // Verify channels are mixed and scaled correctly.
  43. TEST(ChannelMixingMatrixTest, StereoToMono) {
  44. ChannelLayout input_layout = CHANNEL_LAYOUT_STEREO;
  45. ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
  46. ChannelMixingMatrix matrix_builder(
  47. input_layout,
  48. ChannelLayoutToChannelCount(input_layout),
  49. output_layout,
  50. ChannelLayoutToChannelCount(output_layout));
  51. std::vector<std::vector<float>> matrix;
  52. bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
  53. // Input: stereo
  54. // LEFT RIGHT
  55. // Output: mono CENTER 0.5 0.5
  56. //
  57. EXPECT_FALSE(remapping);
  58. EXPECT_EQ(1u, matrix.size());
  59. EXPECT_EQ(2u, matrix[0].size());
  60. EXPECT_EQ(0.5f, matrix[0][0]);
  61. EXPECT_EQ(0.5f, matrix[0][1]);
  62. }
  63. TEST(ChannelMixingMatrixTest, MonoToStereo) {
  64. ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
  65. ChannelLayout output_layout = CHANNEL_LAYOUT_STEREO;
  66. ChannelMixingMatrix matrix_builder(
  67. input_layout,
  68. ChannelLayoutToChannelCount(input_layout),
  69. output_layout,
  70. ChannelLayoutToChannelCount(output_layout));
  71. std::vector<std::vector<float>> matrix;
  72. bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
  73. // Input: mono
  74. // CENTER
  75. // Output: stereo LEFT 1
  76. // RIGHT 1
  77. //
  78. EXPECT_TRUE(remapping);
  79. EXPECT_EQ(2u, matrix.size());
  80. EXPECT_EQ(1u, matrix[0].size());
  81. EXPECT_EQ(1.0f, matrix[0][0]);
  82. EXPECT_EQ(1u, matrix[1].size());
  83. EXPECT_EQ(1.0f, matrix[1][0]);
  84. }
  85. TEST(ChannelMixingMatrixTest, MonoToSurround) {
  86. ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
  87. ChannelLayout output_layout = CHANNEL_LAYOUT_5_1;
  88. ChannelMixingMatrix matrix_builder(
  89. input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
  90. ChannelLayoutToChannelCount(output_layout));
  91. std::vector<std::vector<float>> matrix;
  92. bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
  93. // Input: mono
  94. // CENTER
  95. // Output: surround LEFT 1
  96. // RIGHT 1
  97. // CENTER 0
  98. // LFE 0
  99. // SL 0
  100. // SR 0
  101. //
  102. EXPECT_FALSE(remapping);
  103. EXPECT_EQ(6u, matrix.size());
  104. EXPECT_EQ(1u, matrix[0].size());
  105. EXPECT_EQ(1.0f, matrix[0][0]);
  106. EXPECT_EQ(1u, matrix[1].size());
  107. EXPECT_EQ(1.0f, matrix[1][0]);
  108. for (size_t i = 2; i < 6; i++) {
  109. EXPECT_EQ(1u, matrix[i].size());
  110. EXPECT_EQ(0.0f, matrix[i][0]);
  111. }
  112. }
  113. TEST(ChannelMixingMatrixTest, FiveOneToMono) {
  114. ChannelLayout input_layout = CHANNEL_LAYOUT_5_1;
  115. ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
  116. ChannelMixingMatrix matrix_builder(
  117. input_layout,
  118. ChannelLayoutToChannelCount(input_layout),
  119. output_layout,
  120. ChannelLayoutToChannelCount(output_layout));
  121. std::vector<std::vector<float>> matrix;
  122. bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
  123. // Note: 1/sqrt(2) is shown as 0.707.
  124. //
  125. // Input: 5.1
  126. // LEFT RIGHT CENTER LFE SIDE_LEFT SIDE_RIGHT
  127. // Output: mono CENTER 0.707 0.707 1 0.707 0.707 0.707
  128. //
  129. EXPECT_FALSE(remapping);
  130. EXPECT_EQ(1u, matrix.size());
  131. EXPECT_EQ(6u, matrix[0].size());
  132. EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][0]);
  133. EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][1]);
  134. // The center channel will be mixed at scale 1.
  135. EXPECT_EQ(1.0f, matrix[0][2]);
  136. EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][3]);
  137. EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][4]);
  138. EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][5]);
  139. }
  140. TEST(ChannelMixingMatrixTest, DiscreteToDiscrete) {
  141. const struct {
  142. int input_channels;
  143. int output_channels;
  144. } test_case[] = {
  145. {2, 2}, {2, 5}, {5, 2},
  146. };
  147. for (size_t n = 0; n < std::size(test_case); n++) {
  148. int input_channels = test_case[n].input_channels;
  149. int output_channels = test_case[n].output_channels;
  150. ChannelMixingMatrix matrix_builder(CHANNEL_LAYOUT_DISCRETE,
  151. input_channels,
  152. CHANNEL_LAYOUT_DISCRETE,
  153. output_channels);
  154. std::vector<std::vector<float>> matrix;
  155. bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
  156. EXPECT_TRUE(remapping);
  157. EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
  158. for (int i = 0; i < output_channels; i++) {
  159. EXPECT_EQ(static_cast<size_t>(input_channels), matrix[i].size());
  160. for (int j = 0; j < input_channels; j++) {
  161. if (i == j) {
  162. EXPECT_EQ(1.0f, matrix[i][j]);
  163. } else {
  164. EXPECT_EQ(0.0f, matrix[i][j]);
  165. }
  166. }
  167. }
  168. }
  169. }
  170. } // namespace media