audio_util_unittest.cc (7958B)
1 /* 2 * Copyright (c) 2013 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 "common_audio/include/audio_util.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <iterator> 16 17 #include "api/audio/audio_view.h" 18 #include "test/gmock.h" 19 #include "test/gtest.h" 20 21 namespace webrtc { 22 namespace { 23 24 using ::testing::ElementsAreArray; 25 26 void ExpectArraysEq(const int16_t* ref, const int16_t* test, size_t length) { 27 for (size_t i = 0; i < length; ++i) { 28 EXPECT_EQ(ref[i], test[i]); 29 } 30 } 31 32 void ExpectArraysEq(const float* ref, const float* test, size_t length) { 33 for (size_t i = 0; i < length; ++i) { 34 EXPECT_NEAR(ref[i], test[i], 0.01f); 35 } 36 } 37 38 TEST(AudioUtilTest, S16ToFloat) { 39 static constexpr int16_t kInput[] = {0, 1, -1, 16384, -16384, 32767, -32768}; 40 static constexpr float kReference[] = { 41 0.f, 1.f / 32767.f, -1.f / 32768.f, 16384.f / 32767.f, -0.5f, 1.f, -1.f}; 42 static constexpr size_t kSize = std::size(kInput); 43 static_assert(std::size(kReference) == kSize); 44 float output[kSize]; 45 S16ToFloat(kInput, kSize, output); 46 ExpectArraysEq(kReference, output, kSize); 47 } 48 49 TEST(AudioUtilTest, FloatS16ToS16) { 50 static constexpr float kInput[] = {0.f, 0.4f, 0.5f, -0.4f, 51 -0.5f, 32768.f, -32769.f}; 52 static constexpr int16_t kReference[] = {0, 0, 1, 0, -1, 32767, -32768}; 53 static constexpr size_t kSize = std::size(kInput); 54 static_assert(std::size(kReference) == kSize); 55 int16_t output[kSize]; 56 FloatS16ToS16(kInput, kSize, output); 57 ExpectArraysEq(kReference, output, kSize); 58 } 59 60 TEST(AudioUtilTest, FloatToFloatS16) { 61 static constexpr float kInput[] = {0.f, 62 0.4f / 32768.f, 63 0.6f / 32768.f, 64 -0.4f / 32768.f, 65 -0.6f / 32768.f, 66 1.f, 67 -1.f, 68 1.f, 69 -1.f}; 70 static constexpr float kReference[] = { 71 0.f, 0.4f, 0.6f, -0.4f, -0.6f, 32768.f, -32768.f, 32768.f, -32768.f}; 72 static constexpr size_t kSize = std::size(kInput); 73 static_assert(std::size(kReference) == kSize); 74 float output[kSize]; 75 FloatToFloatS16(kInput, kSize, output); 76 ExpectArraysEq(kReference, output, kSize); 77 } 78 79 TEST(AudioUtilTest, FloatS16ToFloat) { 80 static constexpr float kInput[] = {0.f, 0.4f, 0.6f, -0.4f, -0.6f, 81 32767.f, -32768.f, 32767.f, -32768.f}; 82 static constexpr float kReference[] = {0.f, 83 0.4f / 32768.f, 84 0.6f / 32768.f, 85 -0.4f / 32768.f, 86 -0.6f / 32768.f, 87 1.f, 88 -1.f, 89 1.f, 90 -1.f}; 91 static constexpr size_t kSize = std::size(kInput); 92 static_assert(std::size(kReference) == kSize); 93 float output[kSize]; 94 FloatS16ToFloat(kInput, kSize, output); 95 ExpectArraysEq(kReference, output, kSize); 96 } 97 98 TEST(AudioUtilTest, DbfsToFloatS16) { 99 static constexpr float kInput[] = {-90.f, -70.f, -30.f, -20.f, -10.f, 100 -5.f, -1.f, 0.f, 1.f}; 101 static constexpr float kReference[] = { 102 1.036215186f, 10.36215115f, 1036.215088f, 3276.800049f, 10362.15137f, 103 18426.80078f, 29204.51172f, 32768.f, 36766.30078f}; 104 static constexpr size_t kSize = std::size(kInput); 105 static_assert(std::size(kReference) == kSize); 106 float output[kSize]; 107 for (size_t i = 0; i < kSize; ++i) { 108 output[i] = DbfsToFloatS16(kInput[i]); 109 } 110 ExpectArraysEq(kReference, output, kSize); 111 } 112 113 TEST(AudioUtilTest, FloatS16ToDbfs) { 114 static constexpr float kInput[] = {1.036215143f, 10.36215143f, 1036.215143f, 115 3276.8f, 10362.151436f, 18426.800543f, 116 29204.51074f, 32768.0f, 36766.30071f}; 117 118 static constexpr float kReference[] = { 119 -90.f, -70.f, -30.f, -20.f, -10.f, -5.f, -1.f, 0.f, 0.9999923706f}; 120 static constexpr size_t kSize = std::size(kInput); 121 static_assert(std::size(kReference) == kSize); 122 123 float output[kSize]; 124 for (size_t i = 0; i < kSize; ++i) { 125 output[i] = FloatS16ToDbfs(kInput[i]); 126 } 127 ExpectArraysEq(kReference, output, kSize); 128 } 129 130 TEST(AudioUtilTest, InterleavingStereo) { 131 constexpr int16_t kInterleaved[] = {2, 3, 4, 9, 8, 27, 16, 81}; 132 constexpr size_t kSamplesPerChannel = 4; 133 constexpr int kNumChannels = 2; 134 constexpr size_t kLength = kSamplesPerChannel * kNumChannels; 135 int16_t deinterleaved[kLength] = {}; 136 DeinterleavedView<int16_t> deinterleaved_view( 137 &deinterleaved[0], kSamplesPerChannel, kNumChannels); 138 Deinterleave({&kInterleaved[0], kSamplesPerChannel, kNumChannels}, 139 deinterleaved_view); 140 const int16_t kRefLeft[] = {2, 4, 8, 16}; 141 const int16_t kRefRight[] = {3, 9, 27, 81}; 142 ExpectArraysEq(kRefLeft, deinterleaved_view[0].data(), kSamplesPerChannel); 143 ExpectArraysEq(kRefRight, deinterleaved_view[1].data(), kSamplesPerChannel); 144 145 int16_t interleaved[kLength]; 146 Interleave<int16_t>({&deinterleaved[0], kSamplesPerChannel, kNumChannels}, 147 {&interleaved[0], kSamplesPerChannel, kNumChannels}); 148 ExpectArraysEq(kInterleaved, interleaved, kLength); 149 } 150 151 TEST(AudioUtilTest, InterleavingMonoIsIdentical) { 152 const int16_t kInterleaved[] = {1, 2, 3, 4, 5}; 153 const size_t kSamplesPerChannel = 5; 154 const int kNumChannels = 1; 155 int16_t mono[kSamplesPerChannel]; 156 DeinterleavedView<int16_t> deinterleaved_view(&mono[0], kSamplesPerChannel, 157 kNumChannels); 158 Deinterleave({kInterleaved, kSamplesPerChannel, kNumChannels}, 159 deinterleaved_view); 160 ExpectArraysEq(kInterleaved, deinterleaved_view.AsMono().data(), 161 kSamplesPerChannel); 162 163 int16_t interleaved[kSamplesPerChannel]; 164 Interleave<int16_t>(deinterleaved_view, 165 {&interleaved[0], kSamplesPerChannel, kNumChannels}); 166 ExpectArraysEq(mono, interleaved, kSamplesPerChannel); 167 } 168 169 TEST(AudioUtilTest, DownmixInterleavedToMono) { 170 { 171 const size_t kNumFrames = 4; 172 const int kNumChannels = 1; 173 const int16_t interleaved[kNumChannels * kNumFrames] = {1, 2, -1, -3}; 174 int16_t deinterleaved[kNumFrames]; 175 176 DownmixInterleavedToMono(interleaved, kNumFrames, kNumChannels, 177 deinterleaved); 178 179 EXPECT_THAT(deinterleaved, ElementsAreArray(interleaved)); 180 } 181 { 182 const size_t kNumFrames = 2; 183 const int kNumChannels = 2; 184 const int16_t interleaved[kNumChannels * kNumFrames] = {10, 20, -10, -30}; 185 int16_t deinterleaved[kNumFrames]; 186 187 DownmixInterleavedToMono(interleaved, kNumFrames, kNumChannels, 188 deinterleaved); 189 const int16_t expected[kNumFrames] = {15, -20}; 190 191 EXPECT_THAT(deinterleaved, ElementsAreArray(expected)); 192 } 193 { 194 const size_t kNumFrames = 3; 195 const int kNumChannels = 3; 196 const int16_t interleaved[kNumChannels * kNumFrames] = { 197 30000, 30000, 24001, -5, -10, -20, -30000, -30999, -30000}; 198 int16_t deinterleaved[kNumFrames]; 199 200 DownmixInterleavedToMono(interleaved, kNumFrames, kNumChannels, 201 deinterleaved); 202 const int16_t expected[kNumFrames] = {28000, -11, -30333}; 203 204 EXPECT_THAT(deinterleaved, ElementsAreArray(expected)); 205 } 206 } 207 208 } // namespace 209 } // namespace webrtc