audio_buffer_unittest.cc (3883B)
1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/audio_processing/audio_buffer.h" 12 13 #include <cmath> 14 #include <cstddef> 15 16 #include "api/audio/audio_view.h" 17 #include "rtc_base/checks.h" 18 #include "test/gtest.h" 19 #include "test/testsupport/rtc_expect_death.h" 20 21 namespace webrtc { 22 23 namespace { 24 25 constexpr size_t kSampleRateHz = 48000u; 26 constexpr size_t kStereo = 2u; 27 constexpr size_t kMono = 1u; 28 29 void ExpectNumChannels(const AudioBuffer& ab, size_t num_channels) { 30 EXPECT_EQ(ab.num_channels(), num_channels); 31 } 32 33 } // namespace 34 35 TEST(AudioBufferTest, SetNumChannelsSetsChannelBuffersNumChannels) { 36 AudioBuffer ab(kSampleRateHz, kStereo, kSampleRateHz, kStereo, kSampleRateHz, 37 kStereo); 38 ExpectNumChannels(ab, kStereo); 39 ab.set_num_channels(1); 40 ExpectNumChannels(ab, kMono); 41 ab.RestoreNumChannels(); 42 ExpectNumChannels(ab, kStereo); 43 } 44 45 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 46 TEST(AudioBufferDeathTest, SetNumChannelsDeathTest) { 47 AudioBuffer ab(kSampleRateHz, kMono, kSampleRateHz, kMono, kSampleRateHz, 48 kMono); 49 RTC_EXPECT_DEATH(ab.set_num_channels(kStereo), "num_channels"); 50 } 51 #endif 52 53 TEST(AudioBufferTest, CopyWithoutResampling) { 54 AudioBuffer ab1(32000, 2, 32000, 2, 32000, 2); 55 AudioBuffer ab2(32000, 2, 32000, 2, 32000, 2); 56 // Fill first buffer. 57 for (size_t ch = 0; ch < ab1.num_channels(); ++ch) { 58 for (size_t i = 0; i < ab1.num_frames(); ++i) { 59 ab1.channels()[ch][i] = i + ch; 60 } 61 } 62 // Copy to second buffer. 63 ab1.CopyTo(&ab2); 64 // Verify content of second buffer. 65 for (size_t ch = 0; ch < ab2.num_channels(); ++ch) { 66 for (size_t i = 0; i < ab2.num_frames(); ++i) { 67 EXPECT_EQ(ab2.channels()[ch][i], i + ch); 68 } 69 } 70 } 71 72 TEST(AudioBufferTest, CopyWithResampling) { 73 AudioBuffer ab1(32000, 2, 32000, 2, 48000, 2); 74 AudioBuffer ab2(48000, 2, 48000, 2, 48000, 2); 75 float energy_ab1 = 0.f; 76 float energy_ab2 = 0.f; 77 const float pi = std::acos(-1.f); 78 // Put a sine and compute energy of first buffer. 79 for (size_t ch = 0; ch < ab1.num_channels(); ++ch) { 80 for (size_t i = 0; i < ab1.num_frames(); ++i) { 81 ab1.channels()[ch][i] = std::sin(2 * pi * 100.f / 32000.f * i); 82 energy_ab1 += ab1.channels()[ch][i] * ab1.channels()[ch][i]; 83 } 84 } 85 // Copy to second buffer. 86 ab1.CopyTo(&ab2); 87 // Compute energy of second buffer. 88 for (size_t ch = 0; ch < ab2.num_channels(); ++ch) { 89 for (size_t i = 0; i < ab2.num_frames(); ++i) { 90 energy_ab2 += ab2.channels()[ch][i] * ab2.channels()[ch][i]; 91 } 92 } 93 // Verify that energies match. 94 EXPECT_NEAR(energy_ab1, energy_ab2 * 32000.f / 48000.f, .01f * energy_ab1); 95 } 96 97 TEST(AudioBufferTest, DeinterleavedView) { 98 AudioBuffer ab(48000, 2, 48000, 2, 48000, 2); 99 // Fill the buffer with data. 100 const float pi = std::acos(-1.f); 101 float* const* channels = ab.channels(); 102 for (size_t ch = 0; ch < ab.num_channels(); ++ch) { 103 for (size_t i = 0; i < ab.num_frames(); ++i) { 104 channels[ch][i] = std::sin(2 * pi * 100.f / 32000.f * i); 105 } 106 } 107 108 // Verify that the DeinterleavedView correctly maps to channels. 109 DeinterleavedView<float> view = ab.view(); 110 ASSERT_EQ(view.num_channels(), ab.num_channels()); 111 for (size_t c = 0; c < view.num_channels(); ++c) { 112 MonoView<float> channel = view[c]; 113 EXPECT_EQ(SamplesPerChannel(channel), ab.num_frames()); 114 for (size_t s = 0; s < SamplesPerChannel(channel); ++s) { 115 ASSERT_EQ(channel[s], channels[c][s]); 116 } 117 } 118 } 119 120 } // namespace webrtc