tor-browser

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

fft_data.h (3373B)


      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 #ifndef MODULES_AUDIO_PROCESSING_AEC3_FFT_DATA_H_
     12 #define MODULES_AUDIO_PROCESSING_AEC3_FFT_DATA_H_
     13 
     14 #include <algorithm>
     15 #include <array>
     16 #include <cstddef>
     17 
     18 #include "api/array_view.h"
     19 #include "modules/audio_processing/aec3/aec3_common.h"
     20 #include "rtc_base/checks.h"
     21 
     22 // Defines WEBRTC_ARCH_X86_FAMILY, used below.
     23 #include "rtc_base/system/arch.h"
     24 #if defined(WEBRTC_ARCH_X86_FAMILY)
     25 #include <emmintrin.h>
     26 #endif
     27 
     28 namespace webrtc {
     29 
     30 // Struct that holds imaginary data produced from 128 point real-valued FFTs.
     31 struct FftData {
     32  // Copies the data in src.
     33  void Assign(const FftData& src) {
     34    std::copy(src.re.begin(), src.re.end(), re.begin());
     35    std::copy(src.im.begin(), src.im.end(), im.begin());
     36    im[0] = im[kFftLengthBy2] = 0;
     37  }
     38 
     39  // Clears all the imaginary.
     40  void Clear() {
     41    re.fill(0.f);
     42    im.fill(0.f);
     43  }
     44 
     45  // Computes the power spectrum of the data.
     46  void SpectrumAVX2(ArrayView<float> power_spectrum) const;
     47 
     48  // Computes the power spectrum of the data.
     49  void Spectrum(Aec3Optimization optimization,
     50                ArrayView<float> power_spectrum) const {
     51    RTC_DCHECK_EQ(kFftLengthBy2Plus1, power_spectrum.size());
     52    switch (optimization) {
     53 #if defined(WEBRTC_ARCH_X86_FAMILY)
     54      case Aec3Optimization::kSse2: {
     55        constexpr int kNumFourBinBands = kFftLengthBy2 / 4;
     56        constexpr int kLimit = kNumFourBinBands * 4;
     57        for (size_t k = 0; k < kLimit; k += 4) {
     58          const __m128 r = _mm_loadu_ps(&re[k]);
     59          const __m128 i = _mm_loadu_ps(&im[k]);
     60          const __m128 ii = _mm_mul_ps(i, i);
     61          const __m128 rr = _mm_mul_ps(r, r);
     62          const __m128 rrii = _mm_add_ps(rr, ii);
     63          _mm_storeu_ps(&power_spectrum[k], rrii);
     64        }
     65        power_spectrum[kFftLengthBy2] = re[kFftLengthBy2] * re[kFftLengthBy2] +
     66                                        im[kFftLengthBy2] * im[kFftLengthBy2];
     67      } break;
     68      case Aec3Optimization::kAvx2:
     69        SpectrumAVX2(power_spectrum);
     70        break;
     71 #endif
     72      default:
     73        std::transform(re.begin(), re.end(), im.begin(), power_spectrum.begin(),
     74                       [](float a, float b) { return a * a + b * b; });
     75    }
     76  }
     77 
     78  // Copy the data from an interleaved array.
     79  void CopyFromPackedArray(const std::array<float, kFftLength>& v) {
     80    re[0] = v[0];
     81    re[kFftLengthBy2] = v[1];
     82    im[0] = im[kFftLengthBy2] = 0;
     83    for (size_t k = 1, j = 2; k < kFftLengthBy2; ++k) {
     84      re[k] = v[j++];
     85      im[k] = v[j++];
     86    }
     87  }
     88 
     89  // Copies the data into an interleaved array.
     90  void CopyToPackedArray(std::array<float, kFftLength>* v) const {
     91    RTC_DCHECK(v);
     92    (*v)[0] = re[0];
     93    (*v)[1] = re[kFftLengthBy2];
     94    for (size_t k = 1, j = 2; k < kFftLengthBy2; ++k) {
     95      (*v)[j++] = re[k];
     96      (*v)[j++] = im[k];
     97    }
     98  }
     99 
    100  std::array<float, kFftLengthBy2Plus1> re;
    101  std::array<float, kFftLengthBy2Plus1> im;
    102 };
    103 
    104 }  // namespace webrtc
    105 
    106 #endif  // MODULES_AUDIO_PROCESSING_AEC3_FFT_DATA_H_