summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/resonance-audio/resonance_audio/dsp/partitioned_fft_filter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/resonance-audio/resonance_audio/dsp/partitioned_fft_filter.h')
-rw-r--r--src/3rdparty/resonance-audio/resonance_audio/dsp/partitioned_fft_filter.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/3rdparty/resonance-audio/resonance_audio/dsp/partitioned_fft_filter.h b/src/3rdparty/resonance-audio/resonance_audio/dsp/partitioned_fft_filter.h
new file mode 100644
index 000000000..f8399922a
--- /dev/null
+++ b/src/3rdparty/resonance-audio/resonance_audio/dsp/partitioned_fft_filter.h
@@ -0,0 +1,167 @@
+/*
+Copyright 2018 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS-IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#ifndef RESONANCE_AUDIO_DSP_PARTITIONED_FFT_FILTER_H_
+#define RESONANCE_AUDIO_DSP_PARTITIONED_FFT_FILTER_H_
+
+#include <vector>
+
+#include "base/audio_buffer.h"
+#include "base/misc_math.h"
+#include "dsp/fft_manager.h"
+
+struct PFFFT_Setup;
+
+namespace vraudio {
+
+// Class performing a FFT-based overlap and add FIR convolution.
+// Given an FFT size N and a filter size M > N/2; the filter is broken in to
+// floor(M/(N/2)) partitions in the time domain. This results in a set of
+// frequency domain "filters" of length (N/2)+1.
+class PartitionedFftFilter {
+ public:
+ // Typedef declares the data type for storing frequency domain buffers. Each
+ // channel stores the kernel for a partition.
+ typedef AudioBuffer FreqDomainBuffer;
+
+ // Constructor preallocates memory based on the |filter_size|. This can be
+ // used for simplicity if the filter size will be constant after creation.
+ //
+ // @param filter_size Length of the time domain filter in samples. This will
+ // be increased such that it becomes a multiple of |chunk_size_|.
+ // @param frames_per_buffer Number of points in each time domain input buffer.
+ // @param fft_manager Pointer to a manager to perform FFT transformations.
+ PartitionedFftFilter(size_t filter_size, size_t frames_per_buffer,
+ FftManager* fft_manager);
+
+ // Constructor preallocates memory based on the |max_filter_size|. The
+ // |fft_size_| will be twice |frames_per_buffer| if this is a power of two and
+ // twice the next larger power of two if it is not.
+ //
+ // @param filter_size Length of the time domain filter in samples. This will
+ // be increased such that it becomes a multiple of |chunk_size_|.
+ // @param frames_per_buffer Number of points in each time domain input buffer.
+ // @param max_filter_size Maximum length that |filter_size| can get.
+ // @param fft_manager Pointer to a manager for all fft related functionality.
+ PartitionedFftFilter(size_t filter_size, size_t frames_per_buffer,
+ size_t max_filter_size, FftManager* fft_manager);
+
+ // Initializes the FIR filter from a time domain kernel.
+ //
+ // @parem kernel Time domain filter to be used for processing.
+ void SetTimeDomainKernel(const AudioBuffer::Channel& kernel);
+
+ // Initializes the FIR filter from a precomputed frequency domain kernel.
+ //
+ // @param kernel Frequency domain filter to be used for processing.
+ void SetFreqDomainKernel(const FreqDomainBuffer& kernel);
+
+ // Replaces a partition indicated by the |partition_index| with
+ // |kernel_chunk|'s frequency domain equivalent.
+ //
+ // @param partition_index Location (partition) of the time domain filter we
+ // wish to replace.
+ // @param kernel_chunk |fft_size_|/2 length chunk of a filter used to
+ // replace the |partition_index|th partition.
+ void ReplacePartition(size_t partition_index,
+ const AudioBuffer::Channel& kernel_chunk);
+
+ // Alters the filter length by adding or removing partitions in the frequency
+ // domain. If |new_filter_size| is not a multiple of |chunk_size_| (i.e.
+ // frames per buffer), then the time domain filter kernel will be zeropadded
+ // to a multiple of |chunk_size_|.
+ //
+ // @param new_filter_size New length of the time domain filter kernel.
+ void SetFilterLength(size_t new_filter_size);
+
+ // Processes a block of frequency domain samples. The size of the input
+ // block must be |fft_size_|.
+ //
+ // @param Frequency domain input buffer.
+ void Filter(const FreqDomainBuffer::Channel& input);
+
+ // Returns block of filtered signal output of size |fft_size_|/2.
+ //
+ // @param output Time domain block filtered with the given kernel.
+ void GetFilteredSignal(AudioBuffer::Channel* output);
+
+ // Resets the filter state.
+ void Clear();
+
+ private:
+ friend class PartitionedFftFilterFrequencyBufferTest;
+
+ // Adjusts the |num_partitions_| and the size of |freq_domain_buffers_| for
+ // use with a new time domain filter kernel greater in length than the
+ // previous kernel.
+ //
+ // @param new_kernel_size Length of the time domain filter kernel.
+ void ResetFreqDomainBuffers(size_t new_kernel_size);
+
+ // Manager for all FFT related functionality (not owned).
+ FftManager* const fft_manager_;
+
+ // Number of points in the |fft_manager_|s FFT.
+ const size_t fft_size_;
+
+ // Size of each partition of the filter in time domain.
+ const size_t chunk_size_;
+
+ // Number of frames in each buffer of input data.
+ const size_t frames_per_buffer_;
+
+ // Maximum filter size in samples.
+ const size_t max_filter_size_;
+
+ // Maximum partition count.
+ const size_t max_num_partitions_;
+
+ // Filter size in samples.
+ size_t filter_size_;
+
+ // Partition Count.
+ size_t num_partitions_;
+
+ // Kernel buffer in frequency domain.
+ FreqDomainBuffer kernel_freq_domain_buffer_;
+
+ // Buffer selector to switch between two filtered signal buffers.
+ size_t buffer_selector_;
+
+ // The freq_domain_buffer we will write new incoming audio into.
+ size_t curr_front_buffer_;
+
+ // Frequency domain buffer used to perform filtering.
+ FreqDomainBuffer freq_domain_buffer_;
+
+ // Two buffers that are consecutively filled with filtered signal output.
+ AudioBuffer filtered_time_domain_buffers_;
+
+ // Accumulator for the outputs from each convolution partition
+ FreqDomainBuffer freq_domain_accumulator_;
+
+ // Temporary time domain buffer to store output when zero padding has been
+ // applied due to non power of two input buffer lengths.
+ AudioBuffer temp_zeropad_buffer_;
+
+ // Temporary time domain buffer to hold time domain kernel chunks during
+ // conversion of a kernel from time to frequency domain.
+ AudioBuffer temp_kernel_chunk_buffer_;
+};
+
+} // namespace vraudio
+
+#endif // RESONANCE_AUDIO_DSP_PARTITIONED_FFT_FILTER_H_