channels_tests.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (C) 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. //#define LOG_NDEBUG 0
  17. #define LOG_TAG "audio_utils_channels_tests"
  18. #include <math.h>
  19. #include <vector>
  20. #include <gtest/gtest.h>
  21. #include <log/log.h>
  22. #include <audio_utils/channels.h>
  23. // TODO: Make a common include file for helper functions.
  24. template<typename T>
  25. void checkMonotone(const T *ary, size_t size)
  26. {
  27. for (size_t i = 1; i < size; ++i) {
  28. EXPECT_LT(ary[i-1], ary[i]);
  29. }
  30. }
  31. template<typename T>
  32. void checkUnsignedMonotoneOrZero(const T *ary, size_t size)
  33. {
  34. if (size == 0) return;
  35. T least = ary[0];
  36. for (size_t i = 1; i < size; ++i) {
  37. if (ary[i]) {
  38. EXPECT_LT(least, ary[i]);
  39. least = ary[i];
  40. }
  41. }
  42. }
  43. template<typename T>
  44. void expectEq(const T &c1, const T &c2) {
  45. EXPECT_EQ(c1.size(), c2.size());
  46. EXPECT_EQ(0, memcmp(c1.data(), c2.data(), sizeof(c1[0]) * std::min(c1.size(), c2.size())));
  47. }
  48. TEST(audio_utils_channels, adjust_channels) {
  49. constexpr size_t size = 65536;
  50. std::vector<uint16_t> u16ref(size);
  51. std::vector<uint16_t> u16expand(size * 2);
  52. std::vector<uint16_t> u16ary(size);
  53. // reference buffer is monotonic.
  54. for (size_t i = 0; i < u16ref.size(); ++i) {
  55. u16ref[i] = i;
  56. }
  57. // expand channels from stereo to quad.
  58. adjust_channels(
  59. u16ref.data() /*in_buff*/,
  60. 2 /*in_channels*/,
  61. u16expand.data() /*out_buff*/,
  62. 4 /*out_channels*/,
  63. sizeof(u16ref[0]) /*sample_size_in_bytes*/,
  64. sizeof(u16ref[0]) * u16ref.size() /*num_in_bytes*/);
  65. // expanded buffer must increase (or be zero).
  66. checkUnsignedMonotoneOrZero(u16expand.data(), u16expand.size());
  67. // contract channels back to stereo.
  68. adjust_channels(
  69. u16expand.data() /*in_buff*/,
  70. 4 /*in_channels*/,
  71. u16ary.data() /*out_buff*/,
  72. 2 /*out_channels*/,
  73. sizeof(u16expand[0]) /*sample_size_in_bytes*/,
  74. sizeof(u16expand[0]) * u16expand.size() /*num_in_bytes*/);
  75. // contracted array must be identical to original.
  76. expectEq(u16ary, u16ref);
  77. }
  78. TEST(audio_utils_channels, adjust_selected_channels) {
  79. constexpr size_t size = 65536;
  80. std::vector<uint16_t> u16ref(size);
  81. std::vector<uint16_t> u16contract(size / 2);
  82. std::vector<uint16_t> u16ary(size);
  83. // reference buffer is monotonic.
  84. for (size_t i = 0; i < u16ref.size(); ++i) {
  85. u16ref[i] = i;
  86. }
  87. // contract from quad to stereo.
  88. adjust_selected_channels(
  89. u16ref.data() /*in_buff*/,
  90. 4 /*in_channels*/,
  91. u16contract.data() /*out_buff*/,
  92. 2 /*out_channels*/,
  93. sizeof(u16ref[0]) /*sample_size_in_bytes*/,
  94. sizeof(u16ref[0]) * u16ref.size() /*num_in_bytes*/);
  95. // contracted buffer must increase.
  96. checkMonotone(u16contract.data(), u16contract.size());
  97. // initialize channels 3 and 4 of final comparison array.
  98. for (size_t i = 0; i < u16ary.size() / 4; ++i) {
  99. u16ary[i * 4 + 2] = u16ref[i * 4 + 2];
  100. u16ary[i * 4 + 3] = u16ref[i * 4 + 3];
  101. }
  102. // expand stereo into channels 1 and 2 of quad comparison array.
  103. adjust_selected_channels(
  104. u16contract.data() /*in_buff*/,
  105. 2 /*in_channels*/,
  106. u16ary.data() /*out_buff*/,
  107. 4 /*out_channels*/,
  108. sizeof(u16contract[0]) /*sample_size_in_bytes*/,
  109. sizeof(u16contract[0]) * u16contract.size() /*num_in_bytes*/);
  110. // comparison array must be identical to original.
  111. expectEq(u16ary, u16ref);
  112. }
  113. TEST(audio_utils_channels, adjust_channels_non_destructive) {
  114. constexpr size_t size = 65536; /* arbitrary large multiple of 8 */
  115. std::vector<uint16_t> u16ref(size);
  116. std::vector<uint16_t> u16contracted(size);
  117. std::vector<uint16_t> u16expanded(size);
  118. std::vector<uint16_t> u16inout(size);
  119. // Reference buffer increases monotonically.
  120. // For second test, in/out buffer begins identical to ref.
  121. for (size_t i = 0; i < u16ref.size(); ++i) {
  122. u16ref[i] = i;
  123. u16inout[i] = i;
  124. }
  125. // *** First test: different in/out buffers ***
  126. // Contract from quad to stereo.
  127. adjust_channels_non_destructive(
  128. u16ref.data() /*in_buff*/,
  129. 4 /*in_channels*/,
  130. u16contracted.data() /*out_buff*/,
  131. 2 /*out_channels*/,
  132. sizeof(u16ref[0]) /*sample_size_in_bytes*/,
  133. sizeof(u16ref[0]) * u16ref.size() /*num_in_bytes*/);
  134. // Each half of contracted buffer should increase monotonically.
  135. checkMonotone(u16contracted.data(), u16contracted.size() / 2);
  136. checkMonotone(&u16contracted[u16contracted.size() / 2], u16contracted.size() / 2);
  137. // Expand stereo to quad
  138. adjust_channels_non_destructive(
  139. u16contracted.data() /*in_buff*/,
  140. 2 /*in_channels*/,
  141. u16expanded.data() /*out_buff*/,
  142. 4 /*out_channels*/,
  143. sizeof(u16contracted[0]) /*sample_size_in_bytes*/,
  144. sizeof(u16contracted[0]) * (u16contracted.size() / 2) /*num_in_bytes*/);
  145. // Comparison array must be identical to reference.
  146. expectEq(u16expanded, u16ref);
  147. // *** Second test: in_buff == out_buff ***
  148. // Contract from eight channels to stereo.
  149. adjust_channels_non_destructive(
  150. u16inout.data() /*in_buff*/,
  151. 8 /*in_channels*/,
  152. u16inout.data() /*out_buff*/,
  153. 2 /*out_channels*/,
  154. sizeof(u16inout[0]) /*sample_size_in_bytes*/,
  155. sizeof(u16inout[0]) * u16inout.size() /*num_in_bytes*/);
  156. // Each section [1/4][3/4] of contracted buffer should increase monotonically.
  157. checkMonotone(u16inout.data(), u16inout.size() / 4);
  158. checkMonotone(&u16inout[u16inout.size() / 4], (u16inout.size() * 3) / 4);
  159. // Expand stereo to eight channels.
  160. adjust_channels_non_destructive(
  161. u16inout.data() /*in_buff*/,
  162. 2 /*in_channels*/,
  163. u16inout.data() /*out_buff*/,
  164. 8 /*out_channels*/,
  165. sizeof(u16inout[0]) /*sample_size_in_bytes*/,
  166. sizeof(u16inout[0]) * (u16inout.size() / 4) /*num_in_bytes*/);
  167. // Comparison array must be identical to reference.
  168. expectEq(u16inout, u16ref);
  169. }