| OLD | NEW | 
| (Empty) |  | 
 |    1 /* | 
 |    2  *  Copyright (c) 2017 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 "webrtc/modules/audio_processing/aec3/aec3_fft.h" | 
 |   12  | 
 |   13 #include <algorithm> | 
 |   14  | 
 |   15 #include "webrtc/test/gmock.h" | 
 |   16 #include "webrtc/test/gtest.h" | 
 |   17  | 
 |   18 namespace webrtc { | 
 |   19  | 
 |   20 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 
 |   21  | 
 |   22 // Verifies that the check for non-null input in Fft works. | 
 |   23 TEST(Aec3Fft, NullFftInput) { | 
 |   24   Aec3Fft fft; | 
 |   25   FftData X; | 
 |   26   EXPECT_DEATH(fft.Fft(nullptr, &X), ""); | 
 |   27 } | 
 |   28  | 
 |   29 // Verifies that the check for non-null input in Fft works. | 
 |   30 TEST(Aec3Fft, NullFftOutput) { | 
 |   31   Aec3Fft fft; | 
 |   32   std::array<float, kFftLength> x; | 
 |   33   EXPECT_DEATH(fft.Fft(&x, nullptr), ""); | 
 |   34 } | 
 |   35  | 
 |   36 // Verifies that the check for non-null output in Ifft works. | 
 |   37 TEST(Aec3Fft, NullIfftOutput) { | 
 |   38   Aec3Fft fft; | 
 |   39   FftData X; | 
 |   40   EXPECT_DEATH(fft.Ifft(X, nullptr), ""); | 
 |   41 } | 
 |   42  | 
 |   43 // Verifies that the check for non-null output in ZeroPaddedFft works. | 
 |   44 TEST(Aec3Fft, NullZeroPaddedFftOutput) { | 
 |   45   Aec3Fft fft; | 
 |   46   std::array<float, kFftLengthBy2> x; | 
 |   47   EXPECT_DEATH(fft.ZeroPaddedFft(x, nullptr), ""); | 
 |   48 } | 
 |   49  | 
 |   50 // Verifies that the check for input length in ZeroPaddedFft works. | 
 |   51 TEST(Aec3Fft, ZeroPaddedFftWrongInputLength) { | 
 |   52   Aec3Fft fft; | 
 |   53   FftData X; | 
 |   54   std::array<float, kFftLengthBy2 - 1> x; | 
 |   55   EXPECT_DEATH(fft.ZeroPaddedFft(x, &X), ""); | 
 |   56 } | 
 |   57  | 
 |   58 // Verifies that the check for non-null output in PaddedFft works. | 
 |   59 TEST(Aec3Fft, NullPaddedFftOutput) { | 
 |   60   Aec3Fft fft; | 
 |   61   std::array<float, kFftLengthBy2> x; | 
 |   62   std::array<float, kFftLengthBy2> x_old; | 
 |   63   EXPECT_DEATH(fft.PaddedFft(x, x_old, nullptr), ""); | 
 |   64 } | 
 |   65  | 
 |   66 // Verifies that the check for input length in PaddedFft works. | 
 |   67 TEST(Aec3Fft, PaddedFftWrongInputLength) { | 
 |   68   Aec3Fft fft; | 
 |   69   FftData X; | 
 |   70   std::array<float, kFftLengthBy2 - 1> x; | 
 |   71   std::array<float, kFftLengthBy2> x_old; | 
 |   72   EXPECT_DEATH(fft.PaddedFft(x, x_old, &X), ""); | 
 |   73 } | 
 |   74  | 
 |   75 // Verifies that the check for length in the old value in PaddedFft works. | 
 |   76 TEST(Aec3Fft, PaddedFftWrongOldValuesLength) { | 
 |   77   Aec3Fft fft; | 
 |   78   FftData X; | 
 |   79   std::array<float, kFftLengthBy2> x; | 
 |   80   std::array<float, kFftLengthBy2 - 1> x_old; | 
 |   81   EXPECT_DEATH(fft.PaddedFft(x, x_old, &X), ""); | 
 |   82 } | 
 |   83  | 
 |   84 #endif | 
 |   85  | 
 |   86 // Verifies that Fft works as intended. | 
 |   87 TEST(Aec3Fft, Fft) { | 
 |   88   Aec3Fft fft; | 
 |   89   FftData X; | 
 |   90   std::array<float, kFftLength> x; | 
 |   91   x.fill(0.f); | 
 |   92   fft.Fft(&x, &X); | 
 |   93   EXPECT_THAT(X.re, ::testing::Each(0.f)); | 
 |   94   EXPECT_THAT(X.im, ::testing::Each(0.f)); | 
 |   95  | 
 |   96   x.fill(0.f); | 
 |   97   x[0] = 1.f; | 
 |   98   fft.Fft(&x, &X); | 
 |   99   EXPECT_THAT(X.re, ::testing::Each(1.f)); | 
 |  100   EXPECT_THAT(X.im, ::testing::Each(0.f)); | 
 |  101  | 
 |  102   x.fill(1.f); | 
 |  103   fft.Fft(&x, &X); | 
 |  104   EXPECT_EQ(128.f, X.re[0]); | 
 |  105   std::for_each(X.re.begin() + 1, X.re.end(), | 
 |  106                 [](float a) { EXPECT_EQ(0.f, a); }); | 
 |  107   EXPECT_THAT(X.im, ::testing::Each(0.f)); | 
 |  108 } | 
 |  109  | 
 |  110 // Verifies that InverseFft works as intended. | 
 |  111 TEST(Aec3Fft, Ifft) { | 
 |  112   Aec3Fft fft; | 
 |  113   FftData X; | 
 |  114   std::array<float, kFftLength> x; | 
 |  115  | 
 |  116   X.re.fill(0.f); | 
 |  117   X.im.fill(0.f); | 
 |  118   fft.Ifft(X, &x); | 
 |  119   EXPECT_THAT(x, ::testing::Each(0.f)); | 
 |  120  | 
 |  121   X.re.fill(1.f); | 
 |  122   X.im.fill(0.f); | 
 |  123   fft.Ifft(X, &x); | 
 |  124   EXPECT_EQ(64.f, x[0]); | 
 |  125   std::for_each(x.begin() + 1, x.end(), [](float a) { EXPECT_EQ(0.f, a); }); | 
 |  126  | 
 |  127   X.re.fill(0.f); | 
 |  128   X.re[0] = 128; | 
 |  129   X.im.fill(0.f); | 
 |  130   fft.Ifft(X, &x); | 
 |  131   EXPECT_THAT(x, ::testing::Each(64.f)); | 
 |  132 } | 
 |  133  | 
 |  134 // Verifies that InverseFft and Fft work as intended. | 
 |  135 TEST(Aec3Fft, FftAndIfft) { | 
 |  136   Aec3Fft fft; | 
 |  137   FftData X; | 
 |  138   std::array<float, kFftLength> x; | 
 |  139   std::array<float, kFftLength> x_ref; | 
 |  140  | 
 |  141   int v = 0; | 
 |  142   for (int k = 0; k < 20; ++k) { | 
 |  143     for (size_t j = 0; j < x.size(); ++j) { | 
 |  144       x[j] = v++; | 
 |  145       x_ref[j] = x[j] * 64.f; | 
 |  146     } | 
 |  147     fft.Fft(&x, &X); | 
 |  148     fft.Ifft(X, &x); | 
 |  149     for (size_t j = 0; j < x.size(); ++j) { | 
 |  150       EXPECT_NEAR(x_ref[j], x[j], 0.001f); | 
 |  151     } | 
 |  152   } | 
 |  153 } | 
 |  154  | 
 |  155 // Verifies that ZeroPaddedFft work as intended. | 
 |  156 TEST(Aec3Fft, ZeroPaddedFft) { | 
 |  157   Aec3Fft fft; | 
 |  158   FftData X; | 
 |  159   std::array<float, kFftLengthBy2> x_in; | 
 |  160   std::array<float, kFftLength> x_ref; | 
 |  161   std::array<float, kFftLength> x_out; | 
 |  162  | 
 |  163   int v = 0; | 
 |  164   x_ref.fill(0.f); | 
 |  165   for (int k = 0; k < 20; ++k) { | 
 |  166     for (size_t j = 0; j < x_in.size(); ++j) { | 
 |  167       x_in[j] = v++; | 
 |  168       x_ref[j + kFftLengthBy2] = x_in[j] * 64.f; | 
 |  169     } | 
 |  170     fft.ZeroPaddedFft(x_in, &X); | 
 |  171     fft.Ifft(X, &x_out); | 
 |  172     for (size_t j = 0; j < x_out.size(); ++j) { | 
 |  173       EXPECT_NEAR(x_ref[j], x_out[j], 0.1f); | 
 |  174     } | 
 |  175   } | 
 |  176 } | 
 |  177  | 
 |  178 // Verifies that ZeroPaddedFft work as intended. | 
 |  179 TEST(Aec3Fft, PaddedFft) { | 
 |  180   Aec3Fft fft; | 
 |  181   FftData X; | 
 |  182   std::array<float, kFftLengthBy2> x_in; | 
 |  183   std::array<float, kFftLength> x_out; | 
 |  184   std::array<float, kFftLengthBy2> x_old; | 
 |  185   std::array<float, kFftLengthBy2> x_old_ref; | 
 |  186   std::array<float, kFftLength> x_ref; | 
 |  187  | 
 |  188   int v = 0; | 
 |  189   x_old.fill(0.f); | 
 |  190   for (int k = 0; k < 20; ++k) { | 
 |  191     for (size_t j = 0; j < x_in.size(); ++j) { | 
 |  192       x_in[j] = v++; | 
 |  193     } | 
 |  194  | 
 |  195     std::copy(x_old.begin(), x_old.end(), x_ref.begin()); | 
 |  196     std::copy(x_in.begin(), x_in.end(), x_ref.begin() + kFftLengthBy2); | 
 |  197     std::copy(x_in.begin(), x_in.end(), x_old_ref.begin()); | 
 |  198     std::for_each(x_ref.begin(), x_ref.end(), [](float& a) { a *= 64.f; }); | 
 |  199  | 
 |  200     fft.PaddedFft(x_in, x_old, &X); | 
 |  201     fft.Ifft(X, &x_out); | 
 |  202  | 
 |  203     for (size_t j = 0; j < x_out.size(); ++j) { | 
 |  204       EXPECT_NEAR(x_ref[j], x_out[j], 0.1f); | 
 |  205     } | 
 |  206  | 
 |  207     EXPECT_EQ(x_old_ref, x_old); | 
 |  208   } | 
 |  209 } | 
 |  210  | 
 |  211 }  // namespace webrtc | 
| OLD | NEW |