Repository navigation
Expand file tree
/
Copy pathfft.cpp
More file actions
125 lines (108 loc) · 3.44 KB
/
Copy pathfft.cpp
File metadata and controls
125 lines (108 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "engine/framework/audio/fft.h"
#define ENGINE_SPEECHFFT_CACHE_SIZE 16
#include "detail/speech_fft_internal.h"
#include <stdexcept>
namespace engine::audio {
namespace {
namespace internal_fft = audio_cpp_fft_internal;
using InternalRealPlan = internal_fft::detail::internal_fft_r<float>;
} // namespace
struct RealFFTPlan::Impl {
explicit Impl(size_t fft_size_)
: fft_size(fft_size_),
internal(internal_fft::detail::get_plan<InternalRealPlan>(fft_size_)) {}
size_t fft_size = 0;
std::shared_ptr<InternalRealPlan> internal;
};
RealFFTPlan::RealFFTPlan(size_t fft_size)
: impl_(std::make_shared<Impl>(fft_size)) {
if (fft_size == 0) {
throw std::runtime_error("RealFFTPlan fft_size must be > 0");
}
}
RealFFTPlan::~RealFFTPlan() = default;
RealFFTPlan::RealFFTPlan(const RealFFTPlan &) = default;
RealFFTPlan & RealFFTPlan::operator=(const RealFFTPlan &) = default;
RealFFTPlan::RealFFTPlan(RealFFTPlan &&) noexcept = default;
RealFFTPlan & RealFFTPlan::operator=(RealFFTPlan &&) noexcept = default;
size_t RealFFTPlan::fft_size() const {
return impl_->fft_size;
}
void RealFFTPlan::forward(
const TensorShape & input_shape,
const TensorStrideBytes & input_strides,
const TensorStrideBytes & output_strides,
size_t axis,
const float * data_in,
std::complex<float> * data_out,
float scale,
size_t threads) const {
if (axis >= input_shape.size()) {
throw std::runtime_error("RealFFTPlan forward axis out of range");
}
if (input_shape[axis] != impl_->fft_size) {
throw std::runtime_error("RealFFTPlan forward shape mismatch");
}
real_fft_forward(input_shape, input_strides, output_strides, axis, data_in, data_out, scale, threads);
}
void RealFFTPlan::inverse(
const TensorShape & output_shape,
const TensorStrideBytes & input_strides,
const TensorStrideBytes & output_strides,
size_t axis,
const std::complex<float> * data_in,
float * data_out,
float scale,
size_t threads) const {
if (axis >= output_shape.size()) {
throw std::runtime_error("RealFFTPlan inverse axis out of range");
}
if (output_shape[axis] != impl_->fft_size) {
throw std::runtime_error("RealFFTPlan inverse shape mismatch");
}
real_fft_inverse(output_shape, input_strides, output_strides, axis, data_in, data_out, scale, threads);
}
std::shared_ptr<RealFFTPlan> get_real_fft_plan(size_t fft_size) {
return std::make_shared<RealFFTPlan>(fft_size);
}
void real_fft_forward(
const TensorShape & input_shape,
const TensorStrideBytes & input_strides,
const TensorStrideBytes & output_strides,
size_t axis,
const float * data_in,
std::complex<float> * data_out,
float scale,
size_t threads) {
internal_fft::r2c(
input_shape,
input_strides,
output_strides,
axis,
internal_fft::FORWARD,
data_in,
data_out,
scale,
threads);
}
void real_fft_inverse(
const TensorShape & output_shape,
const TensorStrideBytes & input_strides,
const TensorStrideBytes & output_strides,
size_t axis,
const std::complex<float> * data_in,
float * data_out,
float scale,
size_t threads) {
internal_fft::c2r(
output_shape,
input_strides,
output_strides,
axis,
internal_fft::BACKWARD,
data_in,
data_out,
scale,
threads);
}
} // namespace engine::audio