RavEngine
Loading...
Searching...
No Matches
partitioned_fft_filter.h
1/*
2Copyright 2018 Google Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS-IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef RESONANCE_AUDIO_DSP_PARTITIONED_FFT_FILTER_H_
18#define RESONANCE_AUDIO_DSP_PARTITIONED_FFT_FILTER_H_
19
20#include <vector>
21
22#include "base/audio_buffer.h"
23#include "base/misc_math.h"
24#include "dsp/fft_manager.h"
25
26struct PFFFT_Setup;
27
28namespace vraudio {
29
30// Class performing a FFT-based overlap and add FIR convolution.
31// Given an FFT size N and a filter size M > N/2; the filter is broken in to
32// floor(M/(N/2)) partitions in the time domain. This results in a set of
33// frequency domain "filters" of length (N/2)+1.
35 public:
36 // Typedef declares the data type for storing frequency domain buffers. Each
37 // channel stores the kernel for a partition.
39
40 // Constructor preallocates memory based on the |filter_size|. This can be
41 // used for simplicity if the filter size will be constant after creation.
42 //
43 // @param filter_size Length of the time domain filter in samples. This will
44 // be increased such that it becomes a multiple of |chunk_size_|.
45 // @param frames_per_buffer Number of points in each time domain input buffer.
46 // @param fft_manager Pointer to a manager to perform FFT transformations.
47 PartitionedFftFilter(size_t filter_size, size_t frames_per_buffer,
48 FftManager* fft_manager);
49
50 // Constructor preallocates memory based on the |max_filter_size|. The
51 // |fft_size_| will be twice |frames_per_buffer| if this is a power of two and
52 // twice the next larger power of two if it is not.
53 //
54 // @param filter_size Length of the time domain filter in samples. This will
55 // be increased such that it becomes a multiple of |chunk_size_|.
56 // @param frames_per_buffer Number of points in each time domain input buffer.
57 // @param max_filter_size Maximum length that |filter_size| can get.
58 // @param fft_manager Pointer to a manager for all fft related functionality.
59 PartitionedFftFilter(size_t filter_size, size_t frames_per_buffer,
60 size_t max_filter_size, FftManager* fft_manager);
61
62 // Initializes the FIR filter from a time domain kernel.
63 //
64 // @parem kernel Time domain filter to be used for processing.
65 void SetTimeDomainKernel(const AudioBuffer::Channel& kernel);
66
67 // Initializes the FIR filter from a precomputed frequency domain kernel.
68 //
69 // @param kernel Frequency domain filter to be used for processing.
70 void SetFreqDomainKernel(const FreqDomainBuffer& kernel);
71
72 // Replaces a partition indicated by the |partition_index| with
73 // |kernel_chunk|'s frequency domain equivalent.
74 //
75 // @param partition_index Location (partition) of the time domain filter we
76 // wish to replace.
77 // @param kernel_chunk |fft_size_|/2 length chunk of a filter used to
78 // replace the |partition_index|th partition.
79 void ReplacePartition(size_t partition_index,
80 const AudioBuffer::Channel& kernel_chunk);
81
82 // Alters the filter length by adding or removing partitions in the frequency
83 // domain. If |new_filter_size| is not a multiple of |chunk_size_| (i.e.
84 // frames per buffer), then the time domain filter kernel will be zeropadded
85 // to a multiple of |chunk_size_|.
86 //
87 // @param new_filter_size New length of the time domain filter kernel.
88 void SetFilterLength(size_t new_filter_size);
89
90 // Processes a block of frequency domain samples. The size of the input
91 // block must be |fft_size_|.
92 //
93 // @param Frequency domain input buffer.
94 void Filter(const FreqDomainBuffer::Channel& input);
95
96 // Returns block of filtered signal output of size |fft_size_|/2.
97 //
98 // @param output Time domain block filtered with the given kernel.
99 void GetFilteredSignal(AudioBuffer::Channel* output);
100
101 // Resets the filter state.
102 void Clear();
103
104 private:
106
107 // Adjusts the |num_partitions_| and the size of |freq_domain_buffers_| for
108 // use with a new time domain filter kernel greater in length than the
109 // previous kernel.
110 //
111 // @param new_kernel_size Length of the time domain filter kernel.
112 void ResetFreqDomainBuffers(size_t new_kernel_size);
113
114 // Manager for all FFT related functionality (not owned).
115 FftManager* const fft_manager_;
116
117 // Number of points in the |fft_manager_|s FFT.
118 const size_t fft_size_;
119
120 // Size of each partition of the filter in time domain.
121 const size_t chunk_size_;
122
123 // Number of frames in each buffer of input data.
124 const size_t frames_per_buffer_;
125
126 // Maximum filter size in samples.
127 const size_t max_filter_size_;
128
129 // Maximum partition count.
130 const size_t max_num_partitions_;
131
132 // Filter size in samples.
133 size_t filter_size_;
134
135 // Partition Count.
136 size_t num_partitions_;
137
138 // Kernel buffer in frequency domain.
139 FreqDomainBuffer kernel_freq_domain_buffer_;
140
141 // Buffer selector to switch between two filtered signal buffers.
142 size_t buffer_selector_;
143
144 // The freq_domain_buffer we will write new incoming audio into.
145 size_t curr_front_buffer_;
146
147 // Frequency domain buffer used to perform filtering.
148 FreqDomainBuffer freq_domain_buffer_;
149
150 // Two buffers that are consecutively filled with filtered signal output.
151 AudioBuffer filtered_time_domain_buffers_;
152
153 // Accumulator for the outputs from each convolution partition
154 FreqDomainBuffer freq_domain_accumulator_;
155
156 // Temporary time domain buffer to store output when zero padding has been
157 // applied due to non power of two input buffer lengths.
158 AudioBuffer temp_zeropad_buffer_;
159
160 // Temporary time domain buffer to hold time domain kernel chunks during
161 // conversion of a kernel from time to frequency domain.
162 AudioBuffer temp_kernel_chunk_buffer_;
163};
164
165} // namespace vraudio
166
167#endif // RESONANCE_AUDIO_DSP_PARTITIONED_FFT_FILTER_H_
Definition audio_buffer.h:78
Definition channel_view.h:30
Definition fft_manager.h:28
Definition partitioned_fft_filter_test.cc:461
Definition partitioned_fft_filter.h:34
Definition pffft.c:1197