kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

dft-fft.hpp (4483B)


      1 /** @addtogroup dft
      2  *  @{
      3  */
      4 /*
      5   Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com)
      6   This file is part of KFR
      7 
      8   KFR is free software: you can redistribute it and/or modify
      9   it under the terms of the GNU General Public License as published by
     10   the Free Software Foundation, either version 2 of the License, or
     11   (at your option) any later version.
     12 
     13   KFR is distributed in the hope that it will be useful,
     14   but WITHOUT ANY WARRANTY; without even the implied warranty of
     15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16   GNU General Public License for more details.
     17 
     18   You should have received a copy of the GNU General Public License
     19   along with KFR.
     20 
     21   If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
     22   Buying a commercial license is mandatory as soon as you develop commercial activities without
     23   disclosing the source code of your own applications.
     24   See https://www.kfrlib.com for details.
     25  */
     26 #pragma once
     27 
     28 #include <kfr/base/basic_expressions.hpp>
     29 #include <kfr/math/complex_math.hpp>
     30 #include <kfr/testo/assert.hpp>
     31 #include <kfr/dft/cache.hpp>
     32 #include <kfr/dft/fft.hpp>
     33 #include "bitrev.hpp"
     34 #include "ft.hpp"
     35 
     36 namespace kfr
     37 {
     38 
     39 inline namespace CMT_ARCH_NAME
     40 {
     41 namespace intrinsics
     42 {
     43 struct name_test_impl
     44 {
     45 };
     46 } // namespace intrinsics
     47 } // namespace CMT_ARCH_NAME
     48 
     49 template <typename T, cpu_t cpu>
     50 struct dft_name_impl
     51 {
     52 };
     53 
     54 template <typename Class>
     55 inline const char* dft_name(Class*)
     56 {
     57     constexpr static size_t prefix_len = ctype_name<intrinsics::name_test_impl>().length() - 14;
     58     static constexpr cstring full_name = ctype_name<std::decay_t<Class>>();
     59     static constexpr cstring name_arch =
     60         concat_cstring(full_name.slice(csize<prefix_len>), make_cstring("("),
     61                        make_cstring(CMT_STRINGIFY(CMT_ARCH_NAME)), make_cstring(")"));
     62     return name_arch.c_str();
     63 }
     64 
     65 #define DFT_STAGE_FN                                                                                         \
     66     KFR_MEM_INTRINSIC void do_execute(cdirect_t, complex<T>* out, const complex<T>* in, u8* temp) final      \
     67     {                                                                                                        \
     68         return do_execute<false>(out, in, temp);                                                             \
     69     }                                                                                                        \
     70     KFR_MEM_INTRINSIC void do_execute(cinvert_t, complex<T>* out, const complex<T>* in, u8* temp) final      \
     71     {                                                                                                        \
     72         return do_execute<true>(out, in, temp);                                                              \
     73     }
     74 #define DFT_STAGE_FN_NONFINAL                                                                                \
     75     void do_execute(cdirect_t, complex<T>* out, const complex<T>* in, u8* temp) override                     \
     76     {                                                                                                        \
     77         return do_execute<false>(out, in, temp);                                                             \
     78     }                                                                                                        \
     79     void do_execute(cinvert_t, complex<T>* out, const complex<T>* in, u8* temp) override                     \
     80     {                                                                                                        \
     81         return do_execute<true>(out, in, temp);                                                              \
     82     }
     83 
     84 inline namespace CMT_ARCH_NAME
     85 {
     86 
     87 #define DFT_ASSERT TESTO_ASSERT_INACTIVE
     88 
     89 template <typename T>
     90 constexpr size_t fft_vector_width = vector_width<T>;
     91 
     92 CMT_PRAGMA_GNU(GCC diagnostic push)
     93 #if CMT_HAS_WARNING("-Wassume")
     94 CMT_PRAGMA_GNU(GCC diagnostic ignored "-Wassume")
     95 #endif
     96 
     97 template <typename Stage, bool add_stages = true, typename T, typename... Args>
     98 void add_stage(dft_plan<T>* plan, Args... args)
     99 {
    100     dft_stage<T>* stage = new Stage(args...);
    101     stage->need_reorder = true;
    102     plan->data_size += stage->data_size;
    103     plan->temp_size += stage->temp_size;
    104     plan->all_stages.push_back(dft_stage_ptr<T>(stage));
    105     if constexpr (add_stages)
    106     {
    107         plan->stages[0].push_back(stage);
    108         plan->stages[1].push_back(stage);
    109     }
    110 }
    111 
    112 } // namespace CMT_ARCH_NAME
    113 
    114 } // namespace kfr