audio_bus_unittest.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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/audio_bus.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <limits>
  8. #include <memory>
  9. #include "base/memory/aligned_memory.h"
  10. #include "base/strings/stringprintf.h"
  11. #include "base/test/bind.h"
  12. #include "base/time/time.h"
  13. #include "build/build_config.h"
  14. #include "media/base/audio_parameters.h"
  15. #include "media/base/audio_sample_types.h"
  16. #include "media/base/channel_layout.h"
  17. #include "media/base/fake_audio_render_callback.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. namespace media {
  20. static const int kChannels = 6;
  21. static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1;
  22. // Use a buffer size which is intentionally not a multiple of kChannelAlignment.
  23. static const int kFrameCount = media::AudioBus::kChannelAlignment * 32 - 1;
  24. static const int kSampleRate = 48000;
  25. class AudioBusTest : public testing::Test {
  26. public:
  27. AudioBusTest() = default;
  28. AudioBusTest(const AudioBusTest&) = delete;
  29. AudioBusTest& operator=(const AudioBusTest&) = delete;
  30. ~AudioBusTest() override {
  31. for (size_t i = 0; i < data_.size(); ++i)
  32. base::AlignedFree(data_[i]);
  33. }
  34. void VerifyChannelAndFrameCount(AudioBus* bus) {
  35. EXPECT_EQ(kChannels, bus->channels());
  36. EXPECT_EQ(kFrameCount, bus->frames());
  37. }
  38. void VerifyArrayIsFilledWithValue(const float data[], int size, float value) {
  39. for (int i = 0; i < size; ++i)
  40. ASSERT_FLOAT_EQ(value, data[i]) << "i=" << i;
  41. }
  42. // Verify values for each channel in |result| are within |epsilon| of
  43. // |expected|. If |epsilon| exactly equals 0, uses FLOAT_EQ macro.
  44. void VerifyAreEqualWithEpsilon(const AudioBus* result,
  45. const AudioBus* expected,
  46. float epsilon) {
  47. ASSERT_EQ(expected->channels(), result->channels());
  48. ASSERT_EQ(expected->frames(), result->frames());
  49. ASSERT_EQ(expected->is_bitstream_format(), result->is_bitstream_format());
  50. if (expected->is_bitstream_format()) {
  51. ASSERT_EQ(expected->GetBitstreamDataSize(),
  52. result->GetBitstreamDataSize());
  53. ASSERT_EQ(expected->GetBitstreamFrames(), result->GetBitstreamFrames());
  54. ASSERT_EQ(0, memcmp(expected->channel(0), result->channel(0),
  55. result->GetBitstreamDataSize()));
  56. return;
  57. }
  58. for (int ch = 0; ch < result->channels(); ++ch) {
  59. for (int i = 0; i < result->frames(); ++i) {
  60. SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i));
  61. if (epsilon == 0) {
  62. ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]);
  63. } else {
  64. ASSERT_NEAR(expected->channel(ch)[i], result->channel(ch)[i],
  65. epsilon);
  66. }
  67. }
  68. }
  69. }
  70. // Verify values for each channel in |result| against |expected|.
  71. void VerifyAreEqual(const AudioBus* result, const AudioBus* expected) {
  72. VerifyAreEqualWithEpsilon(result, expected, 0);
  73. }
  74. // Read and write to the full extent of the allocated channel data. Also test
  75. // the Zero() method and verify it does as advertised. Also test data if data
  76. // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.h).
  77. void VerifyReadWriteAndAlignment(AudioBus* bus) {
  78. for (int i = 0; i < bus->channels(); ++i) {
  79. // Verify that the address returned by channel(i) is a multiple of
  80. // AudioBus::kChannelAlignment.
  81. ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(
  82. bus->channel(i)) & (AudioBus::kChannelAlignment - 1));
  83. // Write into the channel buffer.
  84. std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i);
  85. }
  86. for (int i = 0; i < bus->channels(); ++i)
  87. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), i);
  88. bus->Zero();
  89. for (int i = 0; i < bus->channels(); ++i)
  90. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0);
  91. }
  92. // Verify copying to and from |bus1| and |bus2|.
  93. void CopyTest(AudioBus* bus1, AudioBus* bus2) {
  94. // Fill |bus1| with dummy data.
  95. for (int i = 0; i < bus1->channels(); ++i)
  96. std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i);
  97. // Verify copy from |bus1| to |bus2|.
  98. bus2->Zero();
  99. bus1->CopyTo(bus2);
  100. VerifyAreEqual(bus1, bus2);
  101. // Verify copy from |bus2| to |bus1|.
  102. bus1->Zero();
  103. bus2->CopyTo(bus1);
  104. VerifyAreEqual(bus2, bus1);
  105. }
  106. protected:
  107. std::vector<float*> data_;
  108. };
  109. // Verify basic Create(...) method works as advertised.
  110. TEST_F(AudioBusTest, Create) {
  111. std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
  112. VerifyChannelAndFrameCount(bus.get());
  113. VerifyReadWriteAndAlignment(bus.get());
  114. }
  115. // Verify Create(...) using AudioParameters works as advertised.
  116. TEST_F(AudioBusTest, CreateUsingAudioParameters) {
  117. std::unique_ptr<AudioBus> bus = AudioBus::Create(
  118. AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
  119. kSampleRate, kFrameCount));
  120. VerifyChannelAndFrameCount(bus.get());
  121. VerifyReadWriteAndAlignment(bus.get());
  122. }
  123. // Verify an AudioBus created via CreateWrapper(...) works as advertised.
  124. TEST_F(AudioBusTest, CreateWrapper) {
  125. data_.reserve(kChannels);
  126. for (int i = 0; i < kChannels; ++i) {
  127. data_.push_back(static_cast<float*>(base::AlignedAlloc(
  128. sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment)));
  129. }
  130. std::unique_ptr<AudioBus> bus = AudioBus::CreateWrapper(kChannels);
  131. bus->set_frames(kFrameCount);
  132. for (int i = 0; i < bus->channels(); ++i)
  133. bus->SetChannelData(i, data_[i]);
  134. bool deleted = false;
  135. bus->SetWrappedDataDeleter(
  136. base::BindLambdaForTesting([&]() { deleted = true; }));
  137. VerifyChannelAndFrameCount(bus.get());
  138. VerifyReadWriteAndAlignment(bus.get());
  139. EXPECT_FALSE(deleted);
  140. bus.reset();
  141. EXPECT_TRUE(deleted);
  142. }
  143. // Verify an AudioBus created via wrapping a vector works as advertised.
  144. TEST_F(AudioBusTest, WrapVector) {
  145. data_.reserve(kChannels);
  146. for (int i = 0; i < kChannels; ++i) {
  147. data_.push_back(static_cast<float*>(base::AlignedAlloc(
  148. sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment)));
  149. }
  150. std::unique_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_);
  151. VerifyChannelAndFrameCount(bus.get());
  152. VerifyReadWriteAndAlignment(bus.get());
  153. }
  154. // Verify an AudioBus created via wrapping a memory block works as advertised.
  155. TEST_F(AudioBusTest, WrapMemory) {
  156. AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
  157. kSampleRate, kFrameCount);
  158. int data_size = AudioBus::CalculateMemorySize(params);
  159. std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>(
  160. base::AlignedAlloc(data_size, AudioBus::kChannelAlignment)));
  161. // Fill the memory with a test value we can check for after wrapping.
  162. static const float kTestValue = 3;
  163. std::fill(
  164. data.get(), data.get() + data_size / sizeof(*data.get()), kTestValue);
  165. std::unique_ptr<AudioBus> bus = AudioBus::WrapMemory(params, data.get());
  166. // Verify the test value we filled prior to wrapping.
  167. for (int i = 0; i < bus->channels(); ++i)
  168. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kTestValue);
  169. VerifyChannelAndFrameCount(bus.get());
  170. VerifyReadWriteAndAlignment(bus.get());
  171. // Verify the channel vectors lie within the provided memory block.
  172. EXPECT_GE(bus->channel(0), data.get());
  173. EXPECT_LT(bus->channel(bus->channels() - 1) + bus->frames(),
  174. data.get() + data_size / sizeof(*data.get()));
  175. }
  176. // Simulate a shared memory transfer and verify results.
  177. TEST_F(AudioBusTest, CopyTo) {
  178. // Create one bus with AudioParameters and the other through direct values to
  179. // test for parity between the Create() functions.
  180. AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
  181. kSampleRate, kFrameCount);
  182. std::unique_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
  183. std::unique_ptr<AudioBus> bus2 = AudioBus::Create(params);
  184. {
  185. SCOPED_TRACE("Created");
  186. CopyTest(bus1.get(), bus2.get());
  187. }
  188. {
  189. SCOPED_TRACE("Wrapped Vector");
  190. // Try a copy to an AudioBus wrapping a vector.
  191. data_.reserve(kChannels);
  192. for (int i = 0; i < kChannels; ++i) {
  193. data_.push_back(static_cast<float*>(base::AlignedAlloc(
  194. sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment)));
  195. }
  196. bus2 = AudioBus::WrapVector(kFrameCount, data_);
  197. CopyTest(bus1.get(), bus2.get());
  198. }
  199. {
  200. SCOPED_TRACE("Wrapped Memory");
  201. // Try a copy to an AudioBus wrapping a memory block.
  202. std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>(
  203. base::AlignedAlloc(AudioBus::CalculateMemorySize(params),
  204. AudioBus::kChannelAlignment)));
  205. bus2 = AudioBus::WrapMemory(params, data.get());
  206. CopyTest(bus1.get(), bus2.get());
  207. }
  208. }
  209. // Verify Zero() and ZeroFrames(...) utility methods work as advertised.
  210. TEST_F(AudioBusTest, Zero) {
  211. std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
  212. // Fill the bus with dummy data.
  213. for (int i = 0; i < bus->channels(); ++i)
  214. std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
  215. EXPECT_FALSE(bus->AreFramesZero());
  216. // Zero first half the frames of each channel.
  217. bus->ZeroFrames(kFrameCount / 2);
  218. for (int i = 0; i < bus->channels(); ++i) {
  219. SCOPED_TRACE("First Half Zero");
  220. VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, 0);
  221. VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2,
  222. kFrameCount - kFrameCount / 2, i + 1);
  223. }
  224. EXPECT_FALSE(bus->AreFramesZero());
  225. // Fill the bus with dummy data.
  226. for (int i = 0; i < bus->channels(); ++i)
  227. std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
  228. // Zero the last half of the frames.
  229. bus->ZeroFramesPartial(kFrameCount / 2, kFrameCount - kFrameCount / 2);
  230. for (int i = 0; i < bus->channels(); ++i) {
  231. SCOPED_TRACE("Last Half Zero");
  232. VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2,
  233. kFrameCount - kFrameCount / 2, 0);
  234. VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, i + 1);
  235. }
  236. EXPECT_FALSE(bus->AreFramesZero());
  237. // Fill the bus with dummy data.
  238. for (int i = 0; i < bus->channels(); ++i)
  239. std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
  240. // Zero all the frames of each channel.
  241. bus->Zero();
  242. for (int i = 0; i < bus->channels(); ++i) {
  243. SCOPED_TRACE("All Zero");
  244. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0);
  245. }
  246. EXPECT_TRUE(bus->AreFramesZero());
  247. }
  248. // Each test vector represents two channels of data in the following arbitrary
  249. // layout: <min, zero, max, min, max / 2, min / 2, zero, max, zero, zero>.
  250. static const int kTestVectorSize = 10;
  251. static const uint8_t kTestVectorUint8[kTestVectorSize] = {
  252. 0, -INT8_MIN, UINT8_MAX,
  253. 0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128,
  254. -INT8_MIN, UINT8_MAX, -INT8_MIN,
  255. -INT8_MIN};
  256. static const int16_t kTestVectorInt16[kTestVectorSize] = {
  257. INT16_MIN, 0, INT16_MAX, INT16_MIN, INT16_MAX / 2,
  258. INT16_MIN / 2, 0, INT16_MAX, 0, 0};
  259. static const int32_t kTestVectorInt32[kTestVectorSize] = {
  260. INT32_MIN, 0, INT32_MAX, INT32_MIN, INT32_MAX / 2,
  261. INT32_MIN / 2, 0, INT32_MAX, 0, 0};
  262. static const float kTestVectorFloat32[kTestVectorSize] = {
  263. -1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f};
  264. // This is based on kTestVectorFloat32, but has some of the values outside of
  265. // sanity.
  266. static const float kTestVectorFloat32Invalid[kTestVectorSize] = {
  267. -5.0f,
  268. 0.0f,
  269. 5.0f,
  270. -1.0f,
  271. 0.5f,
  272. -0.5f,
  273. 0.0f,
  274. std::numeric_limits<float>::infinity(),
  275. std::numeric_limits<float>::signaling_NaN(),
  276. std::numeric_limits<float>::quiet_NaN()};
  277. static const float kTestVectorFloat32Sanitized[kTestVectorSize] = {
  278. -1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, -1.0f};
  279. // Expected results.
  280. static const int kTestVectorFrameCount = kTestVectorSize / 2;
  281. static const float kTestVectorResult[][kTestVectorFrameCount] = {
  282. {-1.0f, 1.0f, 0.5f, 0.0f, 0.0f},
  283. {0.0f, -1.0f, -0.5f, 1.0f, 0.0f}};
  284. static const int kTestVectorChannelCount = std::size(kTestVectorResult);
  285. // Verify FromInterleaved() deinterleaves audio in supported formats correctly.
  286. TEST_F(AudioBusTest, FromInterleaved) {
  287. std::unique_ptr<AudioBus> bus =
  288. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  289. std::unique_ptr<AudioBus> expected =
  290. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  291. for (int ch = 0; ch < kTestVectorChannelCount; ++ch) {
  292. memcpy(expected->channel(ch), kTestVectorResult[ch],
  293. kTestVectorFrameCount * sizeof(*expected->channel(ch)));
  294. }
  295. {
  296. SCOPED_TRACE("UnsignedInt8SampleTypeTraits");
  297. bus->Zero();
  298. bus->FromInterleaved<UnsignedInt8SampleTypeTraits>(kTestVectorUint8,
  299. kTestVectorFrameCount);
  300. // Biased uint8_t calculations have poor precision, so the epsilon here is
  301. // slightly more permissive than int16_t and int32_t calculations.
  302. VerifyAreEqualWithEpsilon(bus.get(), expected.get(),
  303. 1.0f / (std::numeric_limits<uint8_t>::max() - 1));
  304. }
  305. {
  306. SCOPED_TRACE("SignedInt16SampleTypeTraits");
  307. bus->Zero();
  308. bus->FromInterleaved<SignedInt16SampleTypeTraits>(kTestVectorInt16,
  309. kTestVectorFrameCount);
  310. VerifyAreEqualWithEpsilon(
  311. bus.get(), expected.get(),
  312. 1.0f /
  313. (static_cast<float>(std::numeric_limits<uint16_t>::max()) + 1.0f));
  314. }
  315. {
  316. SCOPED_TRACE("SignedInt32SampleTypeTraits");
  317. bus->Zero();
  318. bus->FromInterleaved<SignedInt32SampleTypeTraits>(kTestVectorInt32,
  319. kTestVectorFrameCount);
  320. VerifyAreEqualWithEpsilon(
  321. bus.get(), expected.get(),
  322. 1.0f / static_cast<float>(std::numeric_limits<uint32_t>::max()));
  323. }
  324. {
  325. SCOPED_TRACE("Float32SampleTypeTraits");
  326. bus->Zero();
  327. bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32,
  328. kTestVectorFrameCount);
  329. VerifyAreEqual(bus.get(), expected.get());
  330. }
  331. }
  332. // Verify FromInterleavedPartial() deinterleaves audio correctly.
  333. TEST_F(AudioBusTest, FromInterleavedPartial) {
  334. // Only deinterleave the middle two frames in each channel.
  335. static const int kPartialStart = 1;
  336. static const int kPartialFrames = 2;
  337. ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount);
  338. std::unique_ptr<AudioBus> bus =
  339. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  340. std::unique_ptr<AudioBus> expected =
  341. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  342. expected->Zero();
  343. for (int ch = 0; ch < kTestVectorChannelCount; ++ch) {
  344. memcpy(expected->channel(ch) + kPartialStart,
  345. kTestVectorResult[ch] + kPartialStart,
  346. kPartialFrames * sizeof(*expected->channel(ch)));
  347. }
  348. {
  349. SCOPED_TRACE("SignedInt32SampleTypeTraits");
  350. bus->Zero();
  351. bus->FromInterleavedPartial<SignedInt32SampleTypeTraits>(
  352. kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart,
  353. kPartialFrames);
  354. VerifyAreEqual(bus.get(), expected.get());
  355. }
  356. }
  357. // Verify ToInterleaved() interleaves audio in suported formats correctly.
  358. TEST_F(AudioBusTest, ToInterleaved) {
  359. std::unique_ptr<AudioBus> bus =
  360. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  361. // Fill the bus with our test vector.
  362. for (int ch = 0; ch < bus->channels(); ++ch) {
  363. memcpy(bus->channel(ch), kTestVectorResult[ch],
  364. kTestVectorFrameCount * sizeof(*bus->channel(ch)));
  365. }
  366. {
  367. SCOPED_TRACE("UnsignedInt8SampleTypeTraits");
  368. uint8_t test_array[std::size(kTestVectorUint8)];
  369. bus->ToInterleaved<UnsignedInt8SampleTypeTraits>(bus->frames(), test_array);
  370. ASSERT_EQ(0,
  371. memcmp(test_array, kTestVectorUint8, sizeof(kTestVectorUint8)));
  372. }
  373. {
  374. SCOPED_TRACE("SignedInt16SampleTypeTraits");
  375. int16_t test_array[std::size(kTestVectorInt16)];
  376. bus->ToInterleaved<SignedInt16SampleTypeTraits>(bus->frames(), test_array);
  377. ASSERT_EQ(0,
  378. memcmp(test_array, kTestVectorInt16, sizeof(kTestVectorInt16)));
  379. }
  380. {
  381. SCOPED_TRACE("SignedInt32SampleTypeTraits");
  382. int32_t test_array[std::size(kTestVectorInt32)];
  383. bus->ToInterleaved<SignedInt32SampleTypeTraits>(bus->frames(), test_array);
  384. // Some compilers get better precision than others on the half-max test, so
  385. // let the test pass with an off by one check on the half-max.
  386. int32_t alternative_acceptable_result[std::size(kTestVectorInt32)];
  387. memcpy(alternative_acceptable_result, kTestVectorInt32,
  388. sizeof(kTestVectorInt32));
  389. ASSERT_EQ(alternative_acceptable_result[4],
  390. std::numeric_limits<int32_t>::max() / 2);
  391. alternative_acceptable_result[4]++;
  392. ASSERT_TRUE(
  393. memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 ||
  394. memcmp(test_array, alternative_acceptable_result,
  395. sizeof(alternative_acceptable_result)) == 0);
  396. }
  397. {
  398. SCOPED_TRACE("Float32SampleTypeTraits");
  399. float test_array[std::size(kTestVectorFloat32)];
  400. bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array);
  401. ASSERT_EQ(
  402. 0, memcmp(test_array, kTestVectorFloat32, sizeof(kTestVectorFloat32)));
  403. }
  404. }
  405. TEST_F(AudioBusTest, ToInterleavedSanitized) {
  406. std::unique_ptr<AudioBus> bus =
  407. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  408. bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32Invalid,
  409. bus->frames());
  410. // Verify FromInterleaved applied no sanity.
  411. ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]);
  412. float test_array[std::size(kTestVectorFloat32Sanitized)];
  413. bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array);
  414. for (size_t i = 0; i < std::size(kTestVectorFloat32Sanitized); ++i)
  415. ASSERT_EQ(kTestVectorFloat32Sanitized[i], test_array[i]);
  416. // Verify that Float32SampleTypeTraitsNoClip applied no sanity. Note: We don't
  417. // use memcmp() here since the NaN type may change on x86 platforms in certain
  418. // circumstances, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57484
  419. bus->ToInterleaved<Float32SampleTypeTraitsNoClip>(bus->frames(), test_array);
  420. for (int i = 0; i < kTestVectorSize; ++i) {
  421. if (std::isnan(test_array[i]))
  422. EXPECT_TRUE(std::isnan(kTestVectorFloat32Invalid[i]));
  423. else
  424. EXPECT_FLOAT_EQ(test_array[i], kTestVectorFloat32Invalid[i]);
  425. }
  426. }
  427. TEST_F(AudioBusTest, CopyAndClipTo) {
  428. auto bus = AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  429. bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32Invalid,
  430. bus->frames());
  431. auto expected =
  432. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  433. expected->FromInterleaved<Float32SampleTypeTraits>(
  434. kTestVectorFloat32Sanitized, bus->frames());
  435. // Verify FromInterleaved applied no sanity.
  436. ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]);
  437. std::unique_ptr<AudioBus> copy_to_bus =
  438. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  439. bus->CopyAndClipTo(copy_to_bus.get());
  440. for (int ch = 0; ch < expected->channels(); ++ch) {
  441. for (int i = 0; i < expected->frames(); ++i)
  442. ASSERT_EQ(copy_to_bus->channel(ch)[i], expected->channel(ch)[i]);
  443. }
  444. ASSERT_EQ(expected->channels(), copy_to_bus->channels());
  445. ASSERT_EQ(expected->frames(), copy_to_bus->frames());
  446. ASSERT_EQ(expected->is_bitstream_format(),
  447. copy_to_bus->is_bitstream_format());
  448. }
  449. // Verify ToInterleavedPartial() interleaves audio correctly.
  450. TEST_F(AudioBusTest, ToInterleavedPartial) {
  451. // Only interleave the middle two frames in each channel.
  452. static const int kPartialStart = 1;
  453. static const int kPartialFrames = 2;
  454. ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount);
  455. std::unique_ptr<AudioBus> expected =
  456. AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount);
  457. for (int ch = 0; ch < kTestVectorChannelCount; ++ch) {
  458. memcpy(expected->channel(ch), kTestVectorResult[ch],
  459. kTestVectorFrameCount * sizeof(*expected->channel(ch)));
  460. }
  461. {
  462. SCOPED_TRACE("Float32SampleTypeTraits");
  463. float test_array[std::size(kTestVectorFloat32)];
  464. expected->ToInterleavedPartial<Float32SampleTypeTraits>(
  465. kPartialStart, kPartialFrames, test_array);
  466. ASSERT_EQ(0, memcmp(test_array, kTestVectorFloat32 +
  467. kPartialStart * kTestVectorChannelCount,
  468. kPartialFrames * sizeof(*kTestVectorFloat32) *
  469. kTestVectorChannelCount));
  470. }
  471. }
  472. struct ZeroingOutTestData {
  473. static constexpr int kChannelCount = 2;
  474. static constexpr int kFrameCount = 10;
  475. static constexpr int kInterleavedFrameCount = 3;
  476. std::unique_ptr<AudioBus> bus_under_test;
  477. std::vector<float> interleaved_dummy_frames;
  478. ZeroingOutTestData() {
  479. // Create a bus and fill each channel with a test pattern of form
  480. // [1.0, 2.0, 3.0, ...]
  481. bus_under_test = AudioBus::Create(kChannelCount, kFrameCount);
  482. for (int ch = 0; ch < kChannelCount; ++ch) {
  483. auto* sample_array_for_current_channel = bus_under_test->channel(ch);
  484. for (int frame_index = 0; frame_index < kFrameCount; frame_index++) {
  485. sample_array_for_current_channel[frame_index] =
  486. static_cast<float>(frame_index + 1);
  487. }
  488. }
  489. // Create a vector containing dummy interleaved samples.
  490. static const float kDummySampleValue = 0.123f;
  491. interleaved_dummy_frames.resize(kChannelCount * kInterleavedFrameCount);
  492. std::fill(interleaved_dummy_frames.begin(), interleaved_dummy_frames.end(),
  493. kDummySampleValue);
  494. }
  495. };
  496. TEST_F(AudioBusTest, FromInterleavedZerosOutUntouchedFrames) {
  497. ZeroingOutTestData test_data;
  498. // Exercise
  499. test_data.bus_under_test->FromInterleaved<Float32SampleTypeTraits>(
  500. &test_data.interleaved_dummy_frames[0], test_data.kInterleavedFrameCount);
  501. // Verification
  502. for (int ch = 0; ch < test_data.kChannelCount; ++ch) {
  503. auto* sample_array_for_current_channel =
  504. test_data.bus_under_test->channel(ch);
  505. for (int frame_index = test_data.kInterleavedFrameCount;
  506. frame_index < test_data.kFrameCount; frame_index++) {
  507. ASSERT_EQ(0.0f, sample_array_for_current_channel[frame_index]);
  508. }
  509. }
  510. }
  511. TEST_F(AudioBusTest, FromInterleavedPartialDoesNotZeroOutUntouchedFrames) {
  512. {
  513. SCOPED_TRACE("Zero write offset");
  514. ZeroingOutTestData test_data;
  515. static const int kWriteOffsetInFrames = 0;
  516. // Exercise
  517. test_data.bus_under_test->FromInterleavedPartial<Float32SampleTypeTraits>(
  518. &test_data.interleaved_dummy_frames[0], kWriteOffsetInFrames,
  519. test_data.kInterleavedFrameCount);
  520. // Verification
  521. for (int ch = 0; ch < test_data.kChannelCount; ++ch) {
  522. auto* sample_array_for_current_channel =
  523. test_data.bus_under_test->channel(ch);
  524. for (int frame_index =
  525. test_data.kInterleavedFrameCount + kWriteOffsetInFrames;
  526. frame_index < test_data.kFrameCount; frame_index++) {
  527. ASSERT_EQ(frame_index + 1,
  528. sample_array_for_current_channel[frame_index]);
  529. }
  530. }
  531. }
  532. {
  533. SCOPED_TRACE("Positive write offset");
  534. ZeroingOutTestData test_data;
  535. static const int kWriteOffsetInFrames = 2;
  536. // Exercise
  537. test_data.bus_under_test->FromInterleavedPartial<Float32SampleTypeTraits>(
  538. &test_data.interleaved_dummy_frames[0], kWriteOffsetInFrames,
  539. test_data.kInterleavedFrameCount);
  540. // Verification
  541. for (int ch = 0; ch < test_data.kChannelCount; ++ch) {
  542. auto* sample_array_for_current_channel =
  543. test_data.bus_under_test->channel(ch);
  544. // Check untouched frames before write offset
  545. for (int frame_index = 0; frame_index < kWriteOffsetInFrames;
  546. frame_index++) {
  547. ASSERT_EQ(frame_index + 1,
  548. sample_array_for_current_channel[frame_index]);
  549. }
  550. // Check untouched frames after write
  551. for (int frame_index =
  552. test_data.kInterleavedFrameCount + kWriteOffsetInFrames;
  553. frame_index < test_data.kFrameCount; frame_index++) {
  554. ASSERT_EQ(frame_index + 1,
  555. sample_array_for_current_channel[frame_index]);
  556. }
  557. }
  558. }
  559. }
  560. TEST_F(AudioBusTest, Scale) {
  561. std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
  562. // Fill the bus with dummy data.
  563. static const float kFillValue = 1;
  564. for (int i = 0; i < bus->channels(); ++i)
  565. std::fill(bus->channel(i), bus->channel(i) + bus->frames(), kFillValue);
  566. // Adjust by an invalid volume and ensure volume is unchanged.
  567. bus->Scale(-1);
  568. for (int i = 0; i < bus->channels(); ++i) {
  569. SCOPED_TRACE("Invalid Scale");
  570. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kFillValue);
  571. }
  572. // Verify correct volume adjustment.
  573. static const float kVolume = 0.5;
  574. bus->Scale(kVolume);
  575. for (int i = 0; i < bus->channels(); ++i) {
  576. SCOPED_TRACE("Half Scale");
  577. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(),
  578. kFillValue * kVolume);
  579. }
  580. // Verify zero volume case.
  581. bus->Scale(0);
  582. for (int i = 0; i < bus->channels(); ++i) {
  583. SCOPED_TRACE("Zero Scale");
  584. VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0);
  585. }
  586. }
  587. TEST_F(AudioBusTest, Bitstream) {
  588. static const size_t kDataSize = kFrameCount / 2;
  589. std::unique_ptr<AudioBus> bus = AudioBus::Create(1, kFrameCount);
  590. EXPECT_FALSE(bus->is_bitstream_format());
  591. bus->set_is_bitstream_format(true);
  592. EXPECT_TRUE(bus->is_bitstream_format());
  593. EXPECT_EQ(size_t{0}, bus->GetBitstreamDataSize());
  594. bus->SetBitstreamDataSize(kDataSize);
  595. EXPECT_EQ(kDataSize, bus->GetBitstreamDataSize());
  596. EXPECT_EQ(0, bus->GetBitstreamFrames());
  597. bus->SetBitstreamFrames(kFrameCount);
  598. EXPECT_EQ(kFrameCount, bus->GetBitstreamFrames());
  599. std::unique_ptr<AudioBus> bus2 = AudioBus::Create(1, kFrameCount);
  600. CopyTest(bus.get(), bus2.get());
  601. bus->Zero();
  602. EXPECT_EQ(size_t{0}, bus->GetBitstreamDataSize());
  603. EXPECT_EQ(0, bus->GetBitstreamFrames());
  604. }
  605. } // namespace media