tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

fft_data_unittest.cc (5184B)


      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 "modules/audio_processing/aec3/fft_data.h"
     12 
     13 #include <array>
     14 #include <cstddef>
     15 
     16 #include "modules/audio_processing/aec3/aec3_common.h"
     17 #include "rtc_base/checks.h"
     18 #include "rtc_base/cpu_info.h"
     19 #include "rtc_base/system/arch.h"
     20 #include "test/gtest.h"
     21 
     22 namespace webrtc {
     23 
     24 #if defined(WEBRTC_ARCH_X86_FAMILY)
     25 // Verifies that the optimized methods are bitexact to their reference
     26 // counterparts.
     27 TEST(FftData, TestSse2Optimizations) {
     28  if (cpu_info::Supports(cpu_info::ISA::kSSE2)) {
     29    FftData x;
     30 
     31    for (size_t k = 0; k < x.re.size(); ++k) {
     32      x.re[k] = k + 1;
     33    }
     34 
     35    x.im[0] = x.im[x.im.size() - 1] = 0.f;
     36    for (size_t k = 1; k < x.im.size() - 1; ++k) {
     37      x.im[k] = 2.f * (k + 1);
     38    }
     39 
     40    std::array<float, kFftLengthBy2Plus1> spectrum;
     41    std::array<float, kFftLengthBy2Plus1> spectrum_sse2;
     42    x.Spectrum(Aec3Optimization::kNone, spectrum);
     43    x.Spectrum(Aec3Optimization::kSse2, spectrum_sse2);
     44    EXPECT_EQ(spectrum, spectrum_sse2);
     45  }
     46 }
     47 
     48 // Verifies that the optimized methods are bitexact to their reference
     49 // counterparts.
     50 TEST(FftData, TestAvx2Optimizations) {
     51  if (cpu_info::Supports(cpu_info::ISA::kAVX2)) {
     52    FftData x;
     53 
     54    for (size_t k = 0; k < x.re.size(); ++k) {
     55      x.re[k] = k + 1;
     56    }
     57 
     58    x.im[0] = x.im[x.im.size() - 1] = 0.f;
     59    for (size_t k = 1; k < x.im.size() - 1; ++k) {
     60      x.im[k] = 2.f * (k + 1);
     61    }
     62 
     63    std::array<float, kFftLengthBy2Plus1> spectrum;
     64    std::array<float, kFftLengthBy2Plus1> spectrum_avx2;
     65    x.Spectrum(Aec3Optimization::kNone, spectrum);
     66    x.Spectrum(Aec3Optimization::kAvx2, spectrum_avx2);
     67    EXPECT_EQ(spectrum, spectrum_avx2);
     68  }
     69 }
     70 #endif
     71 
     72 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
     73 
     74 // Verifies the check for null output in CopyToPackedArray.
     75 TEST(FftDataDeathTest, NonNullCopyToPackedArrayOutput) {
     76  EXPECT_DEATH(FftData().CopyToPackedArray(nullptr), "");
     77 }
     78 
     79 // Verifies the check for null output in Spectrum.
     80 TEST(FftDataDeathTest, NonNullSpectrumOutput) {
     81  EXPECT_DEATH(FftData().Spectrum(Aec3Optimization::kNone, nullptr), "");
     82 }
     83 
     84 #endif
     85 
     86 // Verifies that the Assign method properly copies the data from the source and
     87 // ensures that the imaginary components for the DC and Nyquist bins are 0.
     88 TEST(FftData, Assign) {
     89  FftData x;
     90  FftData y;
     91 
     92  x.re.fill(1.f);
     93  x.im.fill(2.f);
     94  y.Assign(x);
     95  EXPECT_EQ(x.re, y.re);
     96  EXPECT_EQ(0.f, y.im[0]);
     97  EXPECT_EQ(0.f, y.im[x.im.size() - 1]);
     98  for (size_t k = 1; k < x.im.size() - 1; ++k) {
     99    EXPECT_EQ(x.im[k], y.im[k]);
    100  }
    101 }
    102 
    103 // Verifies that the Clear method properly clears all the data.
    104 TEST(FftData, Clear) {
    105  FftData x_ref;
    106  FftData x;
    107 
    108  x_ref.re.fill(0.f);
    109  x_ref.im.fill(0.f);
    110 
    111  x.re.fill(1.f);
    112  x.im.fill(2.f);
    113  x.Clear();
    114 
    115  EXPECT_EQ(x_ref.re, x.re);
    116  EXPECT_EQ(x_ref.im, x.im);
    117 }
    118 
    119 // Verifies that the spectrum is correctly computed.
    120 TEST(FftData, Spectrum) {
    121  FftData x;
    122 
    123  for (size_t k = 0; k < x.re.size(); ++k) {
    124    x.re[k] = k + 1;
    125  }
    126 
    127  x.im[0] = x.im[x.im.size() - 1] = 0.f;
    128  for (size_t k = 1; k < x.im.size() - 1; ++k) {
    129    x.im[k] = 2.f * (k + 1);
    130  }
    131 
    132  std::array<float, kFftLengthBy2Plus1> spectrum;
    133  x.Spectrum(Aec3Optimization::kNone, spectrum);
    134 
    135  EXPECT_EQ(x.re[0] * x.re[0], spectrum[0]);
    136  EXPECT_EQ(x.re[spectrum.size() - 1] * x.re[spectrum.size() - 1],
    137            spectrum[spectrum.size() - 1]);
    138  for (size_t k = 1; k < spectrum.size() - 1; ++k) {
    139    EXPECT_EQ(x.re[k] * x.re[k] + x.im[k] * x.im[k], spectrum[k]);
    140  }
    141 }
    142 
    143 // Verifies that the functionality in CopyToPackedArray works as intended.
    144 TEST(FftData, CopyToPackedArray) {
    145  FftData x;
    146  std::array<float, kFftLength> x_packed;
    147 
    148  for (size_t k = 0; k < x.re.size(); ++k) {
    149    x.re[k] = k + 1;
    150  }
    151 
    152  x.im[0] = x.im[x.im.size() - 1] = 0.f;
    153  for (size_t k = 1; k < x.im.size() - 1; ++k) {
    154    x.im[k] = 2.f * (k + 1);
    155  }
    156 
    157  x.CopyToPackedArray(&x_packed);
    158 
    159  EXPECT_EQ(x.re[0], x_packed[0]);
    160  EXPECT_EQ(x.re[x.re.size() - 1], x_packed[1]);
    161  for (size_t k = 1; k < x_packed.size() / 2; ++k) {
    162    EXPECT_EQ(x.re[k], x_packed[2 * k]);
    163    EXPECT_EQ(x.im[k], x_packed[2 * k + 1]);
    164  }
    165 }
    166 
    167 // Verifies that the functionality in CopyFromPackedArray works as intended
    168 // (relies on that the functionality in CopyToPackedArray has been verified in
    169 // the test above).
    170 TEST(FftData, CopyFromPackedArray) {
    171  FftData x_ref;
    172  FftData x;
    173  std::array<float, kFftLength> x_packed;
    174 
    175  for (size_t k = 0; k < x_ref.re.size(); ++k) {
    176    x_ref.re[k] = k + 1;
    177  }
    178 
    179  x_ref.im[0] = x_ref.im[x_ref.im.size() - 1] = 0.f;
    180  for (size_t k = 1; k < x_ref.im.size() - 1; ++k) {
    181    x_ref.im[k] = 2.f * (k + 1);
    182  }
    183 
    184  x_ref.CopyToPackedArray(&x_packed);
    185  x.CopyFromPackedArray(x_packed);
    186 
    187  EXPECT_EQ(x_ref.re, x.re);
    188  EXPECT_EQ(x_ref.im, x.im);
    189 }
    190 
    191 }  // namespace webrtc