tor-browser

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

real_fft_unittest.cc (3809B)


      1 /*
      2 *  Copyright (c) 2012 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/signal_processing/include/real_fft.h"
     12 
     13 #include <cstdint>
     14 #include <cstdlib>
     15 #include <cstring>
     16 
     17 #include "common_audio/signal_processing/include/signal_processing_library.h"
     18 #include "test/gtest.h"
     19 
     20 namespace webrtc {
     21 namespace {
     22 
     23 // FFT order.
     24 constexpr int kOrder = 5;
     25 // Lengths for real FFT's time and frequency bufffers.
     26 // For N-point FFT, the length requirements from API are N and N+2 respectively.
     27 constexpr int kTimeDataLength = 1 << kOrder;
     28 constexpr int kFreqDataLength = (1 << kOrder) + 2;
     29 // For complex FFT's time and freq buffer. The implementation requires
     30 // 2*N 16-bit words.
     31 constexpr int kComplexFftDataLength = 2 << kOrder;
     32 // Reference data for time signal.
     33 constexpr int16_t kRefData[kTimeDataLength] = {
     34    11739,  6848,  -8688,  31980, -30295, 25242, 27085,  19410,
     35    -26299, 15607, -10791, 11778, -23819, 14498, -25772, 10076,
     36    1173,   6848,  -8688,  31980, -30295, 2522,  27085,  19410,
     37    -2629,  5607,  -3,     1178,  -23819, 1498,  -25772, 10076};
     38 
     39 TEST(RealFFTTest, CreateFailsOnBadInput) {
     40  RealFFT* fft = WebRtcSpl_CreateRealFFT(11);
     41  EXPECT_TRUE(fft == nullptr);
     42  fft = WebRtcSpl_CreateRealFFT(-1);
     43  EXPECT_TRUE(fft == nullptr);
     44 }
     45 
     46 TEST(RealFFTTest, RealAndComplexMatch) {
     47  int i = 0;
     48  int j = 0;
     49  int16_t real_fft_time[kTimeDataLength] = {0};
     50  int16_t real_fft_freq[kFreqDataLength] = {0};
     51  // One common buffer for complex FFT's time and frequency data.
     52  int16_t complex_fft_buff[kComplexFftDataLength] = {0};
     53 
     54  // Prepare the inputs to forward FFT's.
     55  memcpy(real_fft_time, kRefData, sizeof(kRefData));
     56  for (i = 0, j = 0; i < kTimeDataLength; i += 1, j += 2) {
     57    complex_fft_buff[j] = kRefData[i];
     58    complex_fft_buff[j + 1] = 0;  // Insert zero's to imaginary parts.
     59  }
     60 
     61  // Create and run real forward FFT.
     62  RealFFT* fft = WebRtcSpl_CreateRealFFT(kOrder);
     63  EXPECT_TRUE(fft != nullptr);
     64  EXPECT_EQ(0, WebRtcSpl_RealForwardFFT(fft, real_fft_time, real_fft_freq));
     65 
     66  // Run complex forward FFT.
     67  WebRtcSpl_ComplexBitReverse(complex_fft_buff, kOrder);
     68  EXPECT_EQ(0, WebRtcSpl_ComplexFFT(complex_fft_buff, kOrder, 1));
     69 
     70  // Verify the results between complex and real forward FFT.
     71  for (i = 0; i < kFreqDataLength; i++) {
     72    EXPECT_EQ(real_fft_freq[i], complex_fft_buff[i]);
     73  }
     74 
     75  // Prepare the inputs to inverse real FFT.
     76  // We use whatever data in complex_fft_buff[] since we don't care
     77  // about data contents. Only kFreqDataLength 16-bit words are copied
     78  // from complex_fft_buff to real_fft_freq since remaining words (2nd half)
     79  // are conjugate-symmetric to the first half in theory.
     80  memcpy(real_fft_freq, complex_fft_buff, sizeof(real_fft_freq));
     81 
     82  // Run real inverse FFT.
     83  int real_scale = WebRtcSpl_RealInverseFFT(fft, real_fft_freq, real_fft_time);
     84  EXPECT_GE(real_scale, 0);
     85 
     86  // Run complex inverse FFT.
     87  WebRtcSpl_ComplexBitReverse(complex_fft_buff, kOrder);
     88  int complex_scale = WebRtcSpl_ComplexIFFT(complex_fft_buff, kOrder, 1);
     89 
     90  // Verify the results between complex and real inverse FFT.
     91  // They are not bit-exact, since complex IFFT doesn't produce
     92  // exactly conjugate-symmetric data (between first and second half).
     93  EXPECT_EQ(real_scale, complex_scale);
     94  for (i = 0, j = 0; i < kTimeDataLength; i += 1, j += 2) {
     95    EXPECT_LE(abs(real_fft_time[i] - complex_fft_buff[j]), 1);
     96  }
     97 
     98  WebRtcSpl_FreeRealFFT(fft);
     99 }
    100 
    101 }  // namespace
    102 }  // namespace webrtc