audio_latency_unittest.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // Copyright 2016 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/audio_latency.h"
  5. #include <stdint.h>
  6. #include "base/time/time.h"
  7. #include "build/build_config.h"
  8. #include "media/base/limits.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace media {
  11. // Tuple of <sample rate, hardware buffer size, min buffer size, max buffer
  12. // size>.
  13. using AudioLatencyTestData = std::tuple<int, int, int, int>;
  14. class AudioLatencyTest : public testing::TestWithParam<AudioLatencyTestData> {
  15. public:
  16. AudioLatencyTest() = default;
  17. ~AudioLatencyTest() override = default;
  18. void TestExactBufferSizes() {
  19. const int hardware_sample_rate = std::get<0>(GetParam());
  20. const int hardware_buffer_size = std::get<1>(GetParam());
  21. const int min_buffer_size = std::get<2>(GetParam());
  22. const int max_buffer_size = std::get<3>(GetParam());
  23. const int platform_min_buffer_size =
  24. min_buffer_size ? min_buffer_size : hardware_buffer_size;
  25. // Windows 10 may allow exactly the minimum buffer size using the IAudioClient3
  26. // API but any other buffer size must be a multiple of the hardware_buffer_size
  27. // and not the min_buffer_size.
  28. #if BUILDFLAG(IS_WIN)
  29. const int multiplier = hardware_buffer_size;
  30. #else
  31. const int multiplier = platform_min_buffer_size;
  32. #endif
  33. const int platform_max_buffer_size =
  34. max_buffer_size
  35. ? (limits::kMaxWebAudioBufferSize / max_buffer_size) *
  36. max_buffer_size
  37. : (limits::kMaxWebAudioBufferSize / multiplier) * multiplier;
  38. EXPECT_EQ(
  39. platform_min_buffer_size,
  40. media::AudioLatency::GetExactBufferSize(
  41. base::Seconds(0.0), hardware_sample_rate, hardware_buffer_size,
  42. min_buffer_size, max_buffer_size, limits::kMaxWebAudioBufferSize));
  43. EXPECT_EQ(platform_min_buffer_size,
  44. media::AudioLatency::GetExactBufferSize(
  45. base::Seconds(min_buffer_size /
  46. static_cast<double>(hardware_sample_rate)),
  47. hardware_sample_rate, hardware_buffer_size, min_buffer_size,
  48. max_buffer_size, limits::kMaxWebAudioBufferSize));
  49. EXPECT_EQ(multiplier * 2,
  50. media::AudioLatency::GetExactBufferSize(
  51. base::Seconds((multiplier * 2) /
  52. static_cast<double>(hardware_sample_rate)),
  53. hardware_sample_rate, hardware_buffer_size, min_buffer_size,
  54. max_buffer_size, limits::kMaxWebAudioBufferSize));
  55. EXPECT_EQ(multiplier * 2,
  56. media::AudioLatency::GetExactBufferSize(
  57. base::Seconds((multiplier * 1.1) /
  58. static_cast<double>(hardware_sample_rate)),
  59. hardware_sample_rate, hardware_buffer_size, min_buffer_size,
  60. max_buffer_size, limits::kMaxWebAudioBufferSize));
  61. EXPECT_EQ(
  62. platform_max_buffer_size,
  63. media::AudioLatency::GetExactBufferSize(
  64. base::Seconds(10.0), hardware_sample_rate, hardware_buffer_size,
  65. min_buffer_size, max_buffer_size, limits::kMaxWebAudioBufferSize));
  66. if (max_buffer_size) {
  67. EXPECT_EQ(max_buffer_size,
  68. media::AudioLatency::GetExactBufferSize(
  69. base::Seconds(max_buffer_size /
  70. static_cast<double>(hardware_sample_rate)),
  71. hardware_sample_rate, hardware_buffer_size, min_buffer_size,
  72. max_buffer_size, limits::kMaxWebAudioBufferSize));
  73. }
  74. #if BUILDFLAG(IS_WIN)
  75. if (min_buffer_size && min_buffer_size < hardware_buffer_size) {
  76. EXPECT_EQ(hardware_buffer_size,
  77. media::AudioLatency::GetExactBufferSize(
  78. base::Seconds((min_buffer_size * 1.1) /
  79. static_cast<double>(hardware_sample_rate)),
  80. hardware_sample_rate, hardware_buffer_size, min_buffer_size,
  81. max_buffer_size, limits::kMaxWebAudioBufferSize));
  82. }
  83. #elif BUILDFLAG(IS_MAC)
  84. EXPECT_EQ(limits::kMaxWebAudioBufferSize,
  85. media::AudioLatency::GetExactBufferSize(
  86. base::Seconds((limits::kMaxAudioBufferSize * 1.1) /
  87. static_cast<double>(hardware_sample_rate)),
  88. hardware_sample_rate, hardware_buffer_size, min_buffer_size,
  89. max_buffer_size, limits::kMaxWebAudioBufferSize));
  90. #endif
  91. int previous_buffer_size = 0;
  92. for (int i = 0; i < 1000; i++) {
  93. int buffer_size = media::AudioLatency::GetExactBufferSize(
  94. base::Seconds(i / 1000.0), hardware_sample_rate, hardware_buffer_size,
  95. min_buffer_size, max_buffer_size, limits::kMaxWebAudioBufferSize);
  96. EXPECT_GE(buffer_size, previous_buffer_size);
  97. #if BUILDFLAG(IS_WIN)
  98. EXPECT_TRUE(buffer_size == min_buffer_size ||
  99. buffer_size % multiplier == 0 ||
  100. buffer_size % max_buffer_size == 0);
  101. #else
  102. EXPECT_EQ(buffer_size, buffer_size / multiplier * multiplier);
  103. #endif
  104. previous_buffer_size = buffer_size;
  105. }
  106. }
  107. };
  108. // TODO(olka): extend unit tests, use real-world sample rates.
  109. TEST(AudioLatency, HighLatencyBufferSizes) {
  110. #if BUILDFLAG(IS_WIN)
  111. for (int i = 6400; i <= 204800; i *= 2) {
  112. EXPECT_EQ(2 * (i / 100),
  113. AudioLatency::GetHighLatencyBufferSize(i, i / 100));
  114. }
  115. #else
  116. for (int i = 6400; i <= 204800; i *= 2)
  117. #if defined(USE_CRAS)
  118. EXPECT_EQ(8 * (i / 100), AudioLatency::GetHighLatencyBufferSize(i, 32));
  119. #else
  120. EXPECT_EQ(2 * (i / 100), AudioLatency::GetHighLatencyBufferSize(i, 32));
  121. #endif // defined(USE_CRAS)
  122. #endif // BUILDFLAG(IS_WIN)
  123. }
  124. TEST(AudioLatency, InteractiveBufferSizes) {
  125. // The |first| is a requested buffer size and and the |second| is a computed
  126. // "interactive" buffer size from the method.
  127. std::vector<std::pair<int, int>> buffer_size_pairs = {
  128. #if BUILDFLAG(IS_ANDROID)
  129. {64, 128},
  130. {96, 384}, // Pixel 3, 4, 5. (See crbug.com/1090441)
  131. {240, 240}, // Nexus 7
  132. {144, 144}, // Galaxy Nexus
  133. // Irregular device buffer size
  134. {100, 512},
  135. {127, 512},
  136. #else
  137. {64, 64},
  138. #endif // BUILDFLAG(IS_ANDROID)
  139. {128, 128},
  140. {256, 256},
  141. {512, 512},
  142. {1024, 1024},
  143. {2048, 2048}
  144. };
  145. for (auto & buffer_size_pair : buffer_size_pairs) {
  146. EXPECT_EQ(buffer_size_pair.second,
  147. AudioLatency::GetInteractiveBufferSize(buffer_size_pair.first));
  148. }
  149. }
  150. TEST(AudioLatency, RtcBufferSizes) {
  151. for (int i = 6400; i < 204800; i *= 2) {
  152. EXPECT_EQ(i / 100, AudioLatency::GetRtcBufferSize(i, 0));
  153. #if BUILDFLAG(IS_WIN)
  154. EXPECT_EQ(500, AudioLatency::GetRtcBufferSize(i, 500));
  155. #elif BUILDFLAG(IS_ANDROID)
  156. EXPECT_EQ(i / 50, AudioLatency::GetRtcBufferSize(i, i / 50 - 1));
  157. EXPECT_EQ(i / 50 + 1, AudioLatency::GetRtcBufferSize(i, i / 50 + 1));
  158. #else
  159. EXPECT_EQ(i / 100, AudioLatency::GetRtcBufferSize(i, 500));
  160. #endif // BUILDFLAG(IS_WIN)
  161. }
  162. }
  163. TEST_P(AudioLatencyTest, ExactBufferSizes) {
  164. TestExactBufferSizes();
  165. }
  166. INSTANTIATE_TEST_SUITE_P(
  167. All,
  168. AudioLatencyTest,
  169. #if BUILDFLAG(IS_WIN)
  170. // Windows 10 with supported driver will have valid min and max buffer sizes
  171. // whereas older Windows will have zeros. The specific min, max and hardware
  172. // are device-dependent.
  173. testing::Values(std::make_tuple(44100, 440, 128, 440),
  174. std::make_tuple(44100, 440, 440, 440),
  175. std::make_tuple(44100, 440, 440, 880),
  176. std::make_tuple(44100, 440, 440, 4400),
  177. std::make_tuple(44100, 440, 128, 4196),
  178. std::make_tuple(44100, 440, 440, 4196),
  179. std::make_tuple(44100, 440, 0, 0),
  180. std::make_tuple(44100, 256, 128, 512),
  181. std::make_tuple(44100, 256, 0, 0))
  182. #elif BUILDFLAG(IS_MAC) || defined(USE_CRAS)
  183. // These values are constant on Mac and ChromeOS, regardless of device.
  184. testing::Values(std::make_tuple(44100,
  185. 256,
  186. limits::kMinAudioBufferSize,
  187. limits::kMaxAudioBufferSize))
  188. #else
  189. testing::Values(std::make_tuple(44100, 256, 0, 0),
  190. std::make_tuple(44100, 440, 0, 0))
  191. #endif
  192. );
  193. } // namespace media