mixing_graph_impl_unittest.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. // Copyright 2021 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 "services/audio/mixing_graph_impl.h"
  5. #include "media/base/loopback_audio_converter.h"
  6. #include "testing/gmock/include/gmock/gmock.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. namespace audio {
  9. // Wrapper for MixingGraphImpl that exposes converters_ and main_converter_ for
  10. // testing.
  11. class MixingGraphImplUnderTest : public MixingGraphImpl {
  12. public:
  13. MixingGraphImplUnderTest(const media::AudioParameters& output_params,
  14. OnMoreDataCallback on_more_data_cb,
  15. OnErrorCallback on_error_cb,
  16. CreateConverterCallback create_converter_cb)
  17. : MixingGraphImpl(output_params,
  18. on_more_data_cb,
  19. on_error_cb,
  20. create_converter_cb) {}
  21. MixingGraphImplUnderTest(const media::AudioParameters& output_params,
  22. OnMoreDataCallback on_more_data_cb,
  23. OnErrorCallback on_error_cb)
  24. : MixingGraphImpl(output_params, on_more_data_cb, on_error_cb) {}
  25. const auto& converters() { return converters_; }
  26. const auto& main_converter() { return main_converter_; }
  27. };
  28. class MockInput : public MixingGraph::Input {
  29. public:
  30. explicit MockInput(media::AudioParameters params) : params(params) {}
  31. const media::AudioParameters& GetParams() const override { return params; }
  32. MOCK_METHOD(void, SetVolume, (double));
  33. MOCK_METHOD(void, Start, (media::AudioOutputStream::AudioSourceCallback*));
  34. MOCK_METHOD(void, Stop, ());
  35. MOCK_METHOD(double, ProvideInput, (media::AudioBus*, uint32_t));
  36. media::AudioParameters params;
  37. };
  38. class MockConverterFactory {
  39. public:
  40. std::unique_ptr<media::LoopbackAudioConverter> CreateConverter(
  41. const media::AudioParameters& input_params,
  42. const media::AudioParameters& output_params) {
  43. VerifyInput(input_params.sample_rate(), input_params.channel_layout());
  44. VerifyOutput(output_params.sample_rate(), output_params.channel_layout());
  45. return std::make_unique<media::LoopbackAudioConverter>(input_params,
  46. output_params, true);
  47. }
  48. MOCK_METHOD(void, VerifyInput, (int, media::ChannelLayout));
  49. MOCK_METHOD(void, VerifyOutput, (int, media::ChannelLayout));
  50. };
  51. TEST(MixingGraphImpl, AddInputToMainConverter) {
  52. media::AudioParameters output_params(
  53. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  54. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 48000, 480);
  55. MixingGraph::OnMoreDataCallback on_more_data_cb;
  56. MixingGraph::OnErrorCallback on_error_cb;
  57. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  58. on_error_cb);
  59. const auto& converters = mixing_graph.converters();
  60. const auto& main_converter = mixing_graph.main_converter();
  61. EXPECT_EQ(converters.size(), 0UL);
  62. EXPECT_TRUE(main_converter.empty());
  63. // Create a new input with the same audio parameters as the output.
  64. MockInput input(output_params);
  65. mixing_graph.AddInput(&input);
  66. // The input should be connected to the main_converter_.
  67. EXPECT_EQ(converters.size(), 0UL);
  68. EXPECT_FALSE(main_converter.empty());
  69. mixing_graph.RemoveInput(&input);
  70. // Expect main_converter to be empty again.
  71. EXPECT_EQ(converters.size(), 0UL);
  72. EXPECT_TRUE(main_converter.empty());
  73. }
  74. TEST(MixingGraphImpl, AddMultipleInputsToMainConverter) {
  75. media::AudioParameters output_params(
  76. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  77. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 48000, 480);
  78. MixingGraph::OnMoreDataCallback on_more_data_cb;
  79. MixingGraph::OnErrorCallback on_error_cb;
  80. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  81. on_error_cb);
  82. const auto& converters = mixing_graph.converters();
  83. const auto& main_converter = mixing_graph.main_converter();
  84. EXPECT_EQ(converters.size(), 0UL);
  85. EXPECT_TRUE(main_converter.empty());
  86. // Create some new inputs with the same audio parameters as the output.
  87. MockInput input1(output_params);
  88. MockInput input2(output_params);
  89. MockInput input3(output_params);
  90. mixing_graph.AddInput(&input1);
  91. EXPECT_EQ(converters.size(), 0UL);
  92. EXPECT_FALSE(main_converter.empty());
  93. mixing_graph.AddInput(&input2);
  94. EXPECT_EQ(converters.size(), 0UL);
  95. EXPECT_FALSE(main_converter.empty());
  96. mixing_graph.AddInput(&input3);
  97. EXPECT_EQ(converters.size(), 0UL);
  98. EXPECT_FALSE(main_converter.empty());
  99. mixing_graph.RemoveInput(&input1);
  100. EXPECT_EQ(converters.size(), 0UL);
  101. EXPECT_FALSE(main_converter.empty());
  102. mixing_graph.RemoveInput(&input2);
  103. EXPECT_EQ(converters.size(), 0UL);
  104. EXPECT_FALSE(main_converter.empty());
  105. mixing_graph.RemoveInput(&input3);
  106. EXPECT_EQ(converters.size(), 0UL);
  107. EXPECT_TRUE(main_converter.empty());
  108. }
  109. TEST(MixingGraphImpl, AddInputWithChannelMixer) {
  110. media::AudioParameters output_params(
  111. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  112. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 48000, 480);
  113. media::AudioParameters input_params(
  114. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  115. media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 48000, 480);
  116. MixingGraph::OnMoreDataCallback on_more_data_cb;
  117. MixingGraph::OnErrorCallback on_error_cb;
  118. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  119. on_error_cb);
  120. const auto& converters = mixing_graph.converters();
  121. const auto& main_converter = mixing_graph.main_converter();
  122. EXPECT_EQ(converters.size(), 0UL);
  123. EXPECT_TRUE(main_converter.empty());
  124. // Create a new input which differs from the output in number of channels.
  125. MockInput input(input_params);
  126. mixing_graph.AddInput(&input);
  127. // A channel mixer converter should be added to converters_ and connected to
  128. // the main_converter_.
  129. EXPECT_EQ(converters.size(), 1UL);
  130. EXPECT_FALSE(main_converter.empty());
  131. mixing_graph.RemoveInput(&input);
  132. // Expect the channel mixer to have been removed from converters_ and the
  133. // main_converter to be empty again.
  134. EXPECT_EQ(converters.size(), 0UL);
  135. EXPECT_TRUE(main_converter.empty());
  136. }
  137. TEST(MixingGraphImpl, AddInputWithResampler) {
  138. media::AudioParameters output_params(
  139. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  140. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 48000, 480);
  141. media::AudioParameters input_params(
  142. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  143. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 16000, 160);
  144. MixingGraph::OnMoreDataCallback on_more_data_cb;
  145. MixingGraph::OnErrorCallback on_error_cb;
  146. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  147. on_error_cb);
  148. const auto& converters = mixing_graph.converters();
  149. const auto& main_converter = mixing_graph.main_converter();
  150. EXPECT_EQ(converters.size(), 0UL);
  151. EXPECT_TRUE(main_converter.empty());
  152. // Create a new input which differs from the output in sample rate.
  153. MockInput input(input_params);
  154. mixing_graph.AddInput(&input);
  155. // A resampler converter should be added to converters_ and connected to
  156. // the main_converter_.
  157. EXPECT_EQ(converters.size(), 1UL);
  158. EXPECT_FALSE(main_converter.empty());
  159. mixing_graph.RemoveInput(&input);
  160. // Expect the resampler to have been removed from converters_ and the
  161. // main_converter to be empty again.
  162. EXPECT_EQ(converters.size(), 0UL);
  163. EXPECT_TRUE(main_converter.empty());
  164. }
  165. TEST(MixingGraphImpl, OutputDiscreteChannelLayout) {
  166. media::AudioParameters output_params(
  167. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  168. media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE, 48000, 480);
  169. output_params.set_channels_for_discrete(2);
  170. media::AudioParameters input_params(
  171. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  172. media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 48000, 480);
  173. MixingGraph::OnMoreDataCallback on_more_data_cb;
  174. MixingGraph::OnErrorCallback on_error_cb;
  175. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  176. on_error_cb);
  177. const auto& converters = mixing_graph.converters();
  178. const auto& main_converter = mixing_graph.main_converter();
  179. EXPECT_EQ(converters.size(), 0UL);
  180. EXPECT_TRUE(main_converter.empty());
  181. // Create a new input which differs from the output in number of channels.
  182. MockInput input(input_params);
  183. mixing_graph.AddInput(&input);
  184. // A channel mixer converter is used between the non-discrete input and the
  185. // discrete output even though the number of channels is the same.
  186. EXPECT_EQ(converters.size(), 1UL);
  187. EXPECT_FALSE(main_converter.empty());
  188. mixing_graph.RemoveInput(&input);
  189. // Expect the channel mixer to have been removed from converters_ and the
  190. // main_converter to be empty again.
  191. EXPECT_EQ(converters.size(), 0UL);
  192. EXPECT_TRUE(main_converter.empty());
  193. }
  194. TEST(MixingGraphImpl, AddInputWithDiscreteChannelLayout) {
  195. media::AudioParameters output_params(
  196. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  197. media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE, 48000, 480);
  198. output_params.set_channels_for_discrete(1);
  199. media::AudioParameters input_params(
  200. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  201. media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE, 48000, 480);
  202. input_params.set_channels_for_discrete(2);
  203. MixingGraph::OnMoreDataCallback on_more_data_cb;
  204. MixingGraph::OnErrorCallback on_error_cb;
  205. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  206. on_error_cb);
  207. const auto& converters = mixing_graph.converters();
  208. const auto& main_converter = mixing_graph.main_converter();
  209. EXPECT_EQ(converters.size(), 0UL);
  210. EXPECT_TRUE(main_converter.empty());
  211. // Create a new input which differs from the output in number of channels.
  212. MockInput input(input_params);
  213. mixing_graph.AddInput(&input);
  214. // A channel mixer converter should be added to converters_ and connected to
  215. // the main_converter_.
  216. EXPECT_EQ(converters.size(), 1UL);
  217. EXPECT_FALSE(main_converter.empty());
  218. mixing_graph.RemoveInput(&input);
  219. // Expect the channel mixer to have been removed from converters_ and the
  220. // main_converter to be empty again.
  221. EXPECT_EQ(converters.size(), 0UL);
  222. EXPECT_TRUE(main_converter.empty());
  223. }
  224. TEST(MixingGraphImpl, BuildComplexGraph) {
  225. media::AudioParameters output_params(
  226. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  227. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 48000, 480);
  228. MixingGraph::OnMoreDataCallback on_more_data_cb;
  229. MixingGraph::OnErrorCallback on_error_cb;
  230. MixingGraphImplUnderTest mixing_graph(output_params, on_more_data_cb,
  231. on_error_cb);
  232. const auto& converters = mixing_graph.converters();
  233. const auto& main_converter = mixing_graph.main_converter();
  234. EXPECT_EQ(converters.size(), 0UL);
  235. EXPECT_TRUE(main_converter.empty());
  236. // Create a new input which differs from the output in sample rate.
  237. media::AudioParameters input_params_resamp(
  238. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  239. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 16000, 160);
  240. MockInput input1(input_params_resamp);
  241. mixing_graph.AddInput(&input1);
  242. // Graph:
  243. // main <--- converter (resampler) <--- input1
  244. EXPECT_EQ(converters.size(), 1UL);
  245. EXPECT_FALSE(main_converter.empty());
  246. // Adding a new input with the same configuration should not change the
  247. // number of converters.
  248. MockInput input2(input_params_resamp);
  249. mixing_graph.AddInput(&input2);
  250. // Graph:
  251. // main <--- converter (resampler) <--- input1
  252. // <--- input2
  253. EXPECT_EQ(converters.size(), 1UL);
  254. EXPECT_FALSE(main_converter.empty());
  255. // Create a new input which differs from the output in channel layout.
  256. media::AudioParameters input_params_downmix(
  257. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  258. media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 48000, 480);
  259. MockInput input3(input_params_downmix);
  260. mixing_graph.AddInput(&input3);
  261. // Graph:
  262. // main <--- converter (resampler) <--- input1
  263. // <--- input2
  264. // <--- converter (ch. mixer) <--- input3
  265. EXPECT_EQ(converters.size(), 2UL);
  266. EXPECT_FALSE(main_converter.empty());
  267. // Create a new input which needs resampling (re-used) and channel mixing
  268. // (new).
  269. media::AudioParameters input_params_resamp_downmix(
  270. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  271. media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 16000, 160);
  272. MockInput input4(input_params_resamp_downmix);
  273. mixing_graph.AddInput(&input4);
  274. // Graph:
  275. // main <--- converter (resampler) <--- input1
  276. // <--- input2
  277. // <--- converter (ch. mixer) <--- input4
  278. // <--- converter (ch. mixer) <--- input3
  279. EXPECT_EQ(converters.size(), 3UL);
  280. EXPECT_FALSE(main_converter.empty());
  281. // Adding a new input with the same configuration should not change the
  282. // number of converters.
  283. MockInput input5(input_params_resamp_downmix);
  284. mixing_graph.AddInput(&input5);
  285. // Graph:
  286. // main <--- converter (resampler) <--- input1
  287. // <--- input2
  288. // <--- converter (ch. mixer) <--- input4
  289. // <--- input5
  290. // <--- converter (ch. mixer) <--- input3
  291. EXPECT_EQ(converters.size(), 3UL);
  292. EXPECT_FALSE(main_converter.empty());
  293. // Adding a couple of inputs connected directly to the main_converter_
  294. // should not change the number of converters.
  295. MockInput input6(output_params);
  296. MockInput input7(output_params);
  297. mixing_graph.AddInput(&input6);
  298. mixing_graph.AddInput(&input7);
  299. // Graph:
  300. // main <--- converter (resampler) <--- input1
  301. // <--- input2
  302. // <--- converter (ch. mixer) <--- input4
  303. // <--- input5
  304. // <--- converter (ch. mixer) <--- input3
  305. // <--- input6
  306. // <--- input7
  307. EXPECT_EQ(converters.size(), 3UL);
  308. EXPECT_FALSE(main_converter.empty());
  309. // Create a new input which needs resampling (re-used) and channel mixing due
  310. // to having a discrete channel layout.
  311. media::AudioParameters input_params_resamp_discrete(
  312. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  313. media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE, 48000, 160);
  314. input_params_resamp_discrete.set_channels_for_discrete(1);
  315. MockInput input8(input_params_resamp_discrete);
  316. mixing_graph.AddInput(&input8);
  317. // Graph:
  318. // main <--- converter (resampler) <--- input1
  319. // <--- input2
  320. // <--- converter (ch. mixer) <--- input4
  321. // <--- input5
  322. // <--- converter (ch. mixer) <--- input8
  323. // <--- converter (ch. mixer) <--- input3
  324. // <--- input6
  325. // <--- input7
  326. EXPECT_EQ(converters.size(), 4UL);
  327. EXPECT_FALSE(main_converter.empty());
  328. // Removing input{1,2,4,6,7} will not allow any converters to be removed.
  329. mixing_graph.RemoveInput(&input1);
  330. mixing_graph.RemoveInput(&input2);
  331. mixing_graph.RemoveInput(&input4);
  332. mixing_graph.RemoveInput(&input6);
  333. mixing_graph.RemoveInput(&input7);
  334. // Graph:
  335. // main <--- converter (resampler) <--- converter (ch. mixer) <--- input5
  336. // <--- converter (ch. mixer) <--- input8
  337. // <--- converter (ch. mixer) <--- input3
  338. EXPECT_EQ(converters.size(), 4UL);
  339. EXPECT_FALSE(main_converter.empty());
  340. // Removing input8 should cause removal of a channel mixer.
  341. mixing_graph.RemoveInput(&input8);
  342. // Graph:
  343. // main <--- converter (resampler) <--- converter (ch. mixer) <--- input5
  344. // <--- converter (ch. mixer) <--- input3
  345. EXPECT_EQ(converters.size(), 3UL);
  346. EXPECT_FALSE(main_converter.empty());
  347. // Removing input5 should cause removal of the resampler and a channel
  348. // mixer.
  349. mixing_graph.RemoveInput(&input5);
  350. // Graph:
  351. // main <--- converter (ch. mixer) <--- input3
  352. EXPECT_EQ(converters.size(), 1UL);
  353. EXPECT_FALSE(main_converter.empty());
  354. // Removing the last input should result in no converters left and an empty
  355. // main_converter_.
  356. mixing_graph.RemoveInput(&input3);
  357. // Graph:
  358. // main
  359. EXPECT_EQ(converters.size(), 0UL);
  360. EXPECT_TRUE(main_converter.empty());
  361. }
  362. // Builds the same graph as above, but verifies the converter parameters.
  363. TEST(MixingGraphImpl, VerifyConverters) {
  364. media::AudioParameters output_params(
  365. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  366. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 48000, 480);
  367. MockConverterFactory mock_converter_factory;
  368. MixingGraph::OnMoreDataCallback on_more_data_cb;
  369. MixingGraph::OnErrorCallback on_error_cb;
  370. MixingGraphImpl::CreateConverterCallback create_converter_cb =
  371. base::BindRepeating(&MockConverterFactory::CreateConverter,
  372. base::Unretained(&mock_converter_factory));
  373. MixingGraphImpl mixing_graph(output_params, on_more_data_cb, on_error_cb,
  374. create_converter_cb);
  375. // Create a new input which differs from the output in sample rate.
  376. media::AudioParameters input_params_resamp(
  377. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  378. media::ChannelLayout::CHANNEL_LAYOUT_MONO, 16000, 160);
  379. MockInput input1(input_params_resamp);
  380. EXPECT_CALL(mock_converter_factory,
  381. VerifyInput(16000, media::ChannelLayout::CHANNEL_LAYOUT_MONO));
  382. EXPECT_CALL(mock_converter_factory,
  383. VerifyOutput(48000, media::ChannelLayout::CHANNEL_LAYOUT_MONO));
  384. mixing_graph.AddInput(&input1);
  385. // Graph:
  386. // main <--- converter (resampler) <--- input1
  387. // Adding a new input with the same configuration should not change the
  388. // number of converters.
  389. MockInput input2(input_params_resamp);
  390. mixing_graph.AddInput(&input2);
  391. // Graph:
  392. // main <--- converter (resampler) <--- input1
  393. // <--- input2
  394. // Create a new input which differs from the output in channel layout.
  395. media::AudioParameters input_params_downmix(
  396. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  397. media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 48000, 480);
  398. MockInput input3(input_params_downmix);
  399. EXPECT_CALL(mock_converter_factory,
  400. VerifyInput(48000, media::ChannelLayout::CHANNEL_LAYOUT_STEREO));
  401. EXPECT_CALL(mock_converter_factory,
  402. VerifyOutput(48000, media::ChannelLayout::CHANNEL_LAYOUT_MONO));
  403. mixing_graph.AddInput(&input3);
  404. // Graph:
  405. // main <--- converter (resampler) <--- input1
  406. // <--- input2
  407. // <--- converter (ch. mixer) <--- input3
  408. // Create a new input which needs resampling (re-used) and channel mixing
  409. // (new).
  410. media::AudioParameters input_params_resamp_downmix(
  411. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  412. media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 16000, 160);
  413. MockInput input4(input_params_resamp_downmix);
  414. EXPECT_CALL(mock_converter_factory,
  415. VerifyInput(16000, media::ChannelLayout::CHANNEL_LAYOUT_STEREO));
  416. EXPECT_CALL(mock_converter_factory,
  417. VerifyOutput(16000, media::ChannelLayout::CHANNEL_LAYOUT_MONO));
  418. mixing_graph.AddInput(&input4);
  419. // Graph:
  420. // main <--- converter (resampler) <--- input1
  421. // <--- input2
  422. // <--- converter (ch. mixer) <--- input4
  423. // <--- converter (ch. mixer) <--- input3
  424. // Adding a new input with the same configuration should not change the
  425. // number of converters.
  426. MockInput input5(input_params_resamp_downmix);
  427. mixing_graph.AddInput(&input5);
  428. // Graph:
  429. // main <--- converter (resampler) <--- input1
  430. // <--- input2
  431. // <--- converter (ch. mixer) <--- input4
  432. // <--- input5
  433. // <--- converter (ch. mixer) <--- input3
  434. // Create a new input which needs resampling (re-used) and channel mixing due
  435. // to having a discrete channel layout.
  436. media::AudioParameters input_params_resamp_discrete(
  437. media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  438. media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE, 48000, 160);
  439. input_params_resamp_discrete.set_channels_for_discrete(1);
  440. MockInput input6(input_params_resamp_discrete);
  441. EXPECT_CALL(
  442. mock_converter_factory,
  443. VerifyInput(48000, media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE));
  444. EXPECT_CALL(mock_converter_factory,
  445. VerifyOutput(48000, media::ChannelLayout::CHANNEL_LAYOUT_MONO));
  446. mixing_graph.AddInput(&input6);
  447. // Graph:
  448. // main <--- converter (resampler) <--- input1
  449. // <--- input2
  450. // <--- converter (ch. mixer) <--- input4
  451. // <--- input5
  452. // <--- converter (ch. mixer) <--- input6
  453. // <--- converter (ch. mixer) <--- input3
  454. mixing_graph.RemoveInput(&input1);
  455. mixing_graph.RemoveInput(&input2);
  456. mixing_graph.RemoveInput(&input3);
  457. mixing_graph.RemoveInput(&input4);
  458. mixing_graph.RemoveInput(&input5);
  459. mixing_graph.RemoveInput(&input6);
  460. }
  461. // Verifies operator< of AudioConverterKey.
  462. TEST(MixingGraphImpl, AudioConverterKeySorting) {
  463. auto MakeKey = [](media::ChannelLayout channel_layout, int sample_rate) {
  464. return MixingGraphImpl::AudioConverterKey(
  465. media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  466. channel_layout, sample_rate, sample_rate / 100));
  467. };
  468. auto MakeDiscreteKey = [](int channels, int sample_rate) {
  469. media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
  470. media::ChannelLayout::CHANNEL_LAYOUT_DISCRETE,
  471. sample_rate, sample_rate / 100);
  472. params.set_channels_for_discrete(channels);
  473. return MixingGraphImpl::AudioConverterKey(params);
  474. };
  475. // Identical keys.
  476. EXPECT_FALSE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  477. /*sample_rate=*/48000) <
  478. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  479. /*sample_rate=*/48000));
  480. // Sample rate has the highest precedence when sorting.
  481. EXPECT_TRUE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  482. /*sample_rate=*/16000) <
  483. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  484. /*sample_rate=*/48000));
  485. EXPECT_FALSE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  486. /*sample_rate=*/48000) <
  487. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  488. /*sample_rate=*/16000));
  489. EXPECT_TRUE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
  490. /*sample_rate=*/16000) <
  491. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  492. /*sample_rate=*/48000));
  493. EXPECT_FALSE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
  494. /*sample_rate=*/48000) <
  495. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  496. /*sample_rate=*/16000));
  497. EXPECT_TRUE(MakeDiscreteKey(/*channels=*/2,
  498. /*sample_rate=*/16000) <
  499. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  500. /*sample_rate=*/48000));
  501. EXPECT_FALSE(MakeDiscreteKey(/*channels=*/2,
  502. /*sample_rate=*/48000) <
  503. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  504. /*sample_rate=*/16000));
  505. EXPECT_FALSE(MakeDiscreteKey(/*channels=*/1,
  506. /*sample_rate=*/48000) <
  507. MakeDiscreteKey(/*channels=*/2,
  508. /*sample_rate=*/16000));
  509. // Channel layout has the second highest precedence when sorting.
  510. EXPECT_TRUE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  511. /*sample_rate=*/48000) <
  512. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
  513. /*sample_rate=*/48000));
  514. EXPECT_FALSE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
  515. /*sample_rate=*/48000) <
  516. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  517. /*sample_rate=*/48000));
  518. EXPECT_TRUE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  519. /*sample_rate=*/48000) <
  520. MakeDiscreteKey(/*channels=*/2,
  521. /*sample_rate=*/48000));
  522. EXPECT_FALSE(MakeDiscreteKey(/*channels=*/2,
  523. /*sample_rate=*/48000) <
  524. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
  525. /*sample_rate=*/48000));
  526. EXPECT_TRUE(MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
  527. /*sample_rate=*/48000) <
  528. MakeDiscreteKey(/*channels=*/2,
  529. /*sample_rate=*/48000));
  530. EXPECT_FALSE(MakeDiscreteKey(/*channels=*/2,
  531. /*sample_rate=*/48000) <
  532. MakeKey(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
  533. /*sample_rate=*/48000));
  534. // Number of channels determines sort order when comparing two keys with the
  535. // same sampling rate and discrete channel layout.
  536. EXPECT_FALSE(MakeDiscreteKey(/*channels=*/1,
  537. /*sample_rate=*/48000) <
  538. MakeDiscreteKey(/*channels=*/1,
  539. /*sample_rate=*/48000));
  540. EXPECT_TRUE(MakeDiscreteKey(/*channels=*/1,
  541. /*sample_rate=*/48000) <
  542. MakeDiscreteKey(/*channels=*/2,
  543. /*sample_rate=*/48000));
  544. EXPECT_FALSE(MakeDiscreteKey(/*channels=*/2,
  545. /*sample_rate=*/48000) <
  546. MakeDiscreteKey(/*channels=*/1,
  547. /*sample_rate=*/48000));
  548. }
  549. } // namespace audio