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_SPECTRAL_REVERB_H_
18#define RESONANCE_AUDIO_DSP_SPECTRAL_REVERB_H_
19
20#include <memory>
21#include <vector>
22
23#include "base/audio_buffer.h"
24#include "dsp/circular_buffer.h"
25#include "dsp/fft_manager.h"
26
27namespace vraudio {
28
29// Implements a spectral reverb producing a decorrelated stereo output. See:
30// [1] E. Vickers, J-L Wu, P.G. Krishnan, R. N. K. Sadanandam, "Frequency Domain
31// Artificial Reverberation using Spectral Magnitude Decay",
32// https://goo.gl/hv1pdJ.
33class SpectralReverb {
34 public:
35 // Constructs a spectral reverb.
36 //
37 // @param sample_rate The system sample rate.
38 // @param frames_per_buffer System frames per buffer of input and output.
39 // Note that this class expects power of two buffers of input and output.
40 SpectralReverb(int sample_rate, size_t frames_per_buffer);
41
42 // Sets the overall gain to be applied to the output of the reverb.
43 //
44 // @param gain Gain to be applied to the reverb output, min value 0.0f.
45 void SetGain(float gain);
46
47 // Sets the |SpectralReverb|'s reverberation times in different frequency
48 // bands. Supports times between:
49 // (0.15 * 48000 / |sample_rate|)s and (25 * 48000 / |sample_rate|)s.
50 //
51 // @param rt60_values |kNumReverbOctaveBands| values denoting the
52 // reverberation decay time to -60dB in octave bands starting at
53 // |kLowestOctaveBand|.
54 void SetRt60PerOctaveBand(const float* rt60_values);
55
56 // Applies reverb to an input channel of audio data and produces a stereo
57 // output.
58 //
59 // @param input Mono inpu data.
60 // @param left_out Left channel of reverberated output.
61 // @param right_out Right channel of reverberated output.
62 void Process(const AudioBuffer::Channel& input,
63 AudioBuffer::Channel* left_out, AudioBuffer::Channel* right_out);
64
65 private:
66 // Uses an AudioBuffer with four channels to overlap add and insert the final
67 // reverb into the output circular buffers.
68 //
69 // @param channel_index Denotes the (left or right) channel to output to.
70 // @param buffer The buffer to be added onto the pre-existing reverb output.
71 void AccumulateOverlap(size_t channel_index,
72 const AudioBuffer::Channel& buffer);
73
74 // Generates a window function which is a normalized sum of three overlapping
75 // (50%) hann windows of length (|kFftSize| / 2) that also incorporates the
76 // inverse fft scaling.
77 void GenerateAnalysisWindow();
78
79 // Generates a large buffer of sines and cosines of random noise between 0 and
80 // pi to be randomly indexed into in order to cheaply generate highly
81 // decorrelated phase buffers,
82 void GenerateRandomPhaseBuffer();
83
84 // Obtains the next stero pair of time domain reverb blocks which can then be
85 // summed together in an overlap add fashion to provide the reverb output.
86 //
87 // @param delay_index An index into the frequency domain magnitude ring
88 // buffer.
89 // @param left_channel Channel to contain the left partial reverb output.
90 // @param right_channel Channel to contain the right partial reverb output.
91 void GetNextReverbBlock(size_t delay_index,
92 AudioBuffer::Channel* left_channel,
93 AudioBuffer::Channel* right_channel);
94
95 // Initializes the output circular buffers such that they contain zeros if the
96 // value of |frames_per_buffer_| is sufficiently smaller than that of
97 // |kOverlapLength| that buffering of input will be required prior to
98 // processing. Also allocates memory for the output accumulators.
99 void InitializeCircularBuffersAndAccumulators();
100
101 // System sample rate.
102 const int sample_rate_;
103
104 // System frames per buffer.
105 const size_t frames_per_buffer_;
106
107 // Indices into the magnitude and overlap add delay lines, modulo of their
108 // respective lengths.
109 size_t magnitude_delay_index_;
110 size_t overlap_add_index_;
111
112 // Manages the time-frequency transforms and phase/magnitude-frequency
113 // transforms.
114 FftManager fft_manager_;
115
116 // Buffer containing sines and cosines of random values between 0 and pi to be
117 // used for phase.
118 AudioBuffer sin_cos_random_phase_buffer_;
119
120 // Buffer containing a triple overlapping hann window for windowing time
121 // domain data.
122 AudioBuffer unscaled_window_;
123
124 // Buffer containing a triple overlapping hann window for windowing time
125 // domain data, this window has been scaled by the output gain factor.
126 AudioBuffer window_;
127
128 // Buffer containing RT60 tuned feedback values.
129 AudioBuffer feedback_;
130
131 // Buffer used to store scaling values which account for the different initial
132 // peak magnitudes for different RT60s.
133 AudioBuffer magnitude_compensation_;
134
135 // Buffer that acts as the frequency domain magnitde delay.
136 AudioBuffer magnitude_delay_;
137
138 // Buffer to contain a linear |kFftSize| chunk of input data.
139 AudioBuffer fft_size_input_;
140
141 // Circular buffers to sit at the input and output of the |Process()| method
142 // to allow |frames_per_buffer_| to differ from |kFftSize|.
143 CircularBuffer input_circular_buffer_;
144 std::vector<std::unique_ptr<CircularBuffer>> output_circular_buffers_;
145
146 // Time domain buffer used to store reverb before the overlap add operation.
147 AudioBuffer out_time_buffer_;
148
149 // Temporary frequency domain buffer, used to store frequency domain data when
150 // transforming between Pffft and Canonical format frequency domain data.
151 AudioBuffer temp_freq_buffer_;
152
153 // Buffer used to store feedback scaled magnitude values.
154 AudioBuffer scaled_magnitude_buffer_;
155
156 // Buffer used for the accumulation of scaled magnitude buffers.
157 AudioBuffer temp_magnitude_buffer_;
158
159 // Buffer used to store randomized phase.
160 AudioBuffer temp_phase_buffer_;
161
162 // Buffers used to calculate the overlap add at the output.
163 std::vector<AudioBuffer> output_accumulator_;
164
165 // Processing of the spectral reverb is bypassed when the feedback values are
166 // all approximately zero OR when the gain is set to near zero.
167 bool is_gain_near_zero_;
168 bool is_feedback_near_zero_;
169};
170
171} // namespace vraudio
172
173#endif // RESONANCE_AUDIO_DSP_SPECTRAL_REVERB_H_
174

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/dsp/spectral_reverb.h