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