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#include "dsp/near_field_processor.h"
18
19#include "base/constants_and_types.h"
20#include "dsp/filter_coefficient_generators.h"
21#include "dsp/gain.h"
22
23namespace vraudio {
24
25namespace {
26
27// Cross-over frequency of the band-splitting filter.
28const float kCrossOverFrequencyHz = 1000.0f;
29
30// +6dB bass boost factor converted to linear scale.
31const float kBassBoost = 2.0f;
32
33// Average group delay of the HRTF filters in seconds. Please see
34// [internal ref]
35const float kMeanHrtfGroupDelaySeconds = 0.00066667f;
36
37// Average group delay of the shelf-filter in samples.
38const size_t kMeanShelfFilterGroupDelaySamples = 1;
39
40} // namespace
41
42NearFieldProcessor::NearFieldProcessor(int sample_rate,
43 size_t frames_per_buffer)
44 : frames_per_buffer_(frames_per_buffer),
45 delay_compensation_(static_cast<size_t>(kMeanHrtfGroupDelaySeconds *
46 static_cast<float>(sample_rate)) -
47 kMeanShelfFilterGroupDelaySamples),
48 lo_pass_filter_(BiquadCoefficients(), frames_per_buffer_),
49 hi_pass_filter_(BiquadCoefficients(), frames_per_buffer_),
50 low_passed_buffer_(kNumMonoChannels, frames_per_buffer_),
51 delay_filter_(delay_compensation_, frames_per_buffer_) {
52 DCHECK_GT(sample_rate, 0);
53 DCHECK_GT(frames_per_buffer, 0);
54 DCHECK_LT(kCrossOverFrequencyHz, 0.5f * static_cast<float>(sample_rate));
55
56 // Generate biquad coefficients and construct low- and high-pass filter
57 // states.
58 BiquadCoefficients lo_pass_coefficients;
59 BiquadCoefficients hi_pass_coefficients;
60 ComputeDualBandBiquadCoefficients(sample_rate, crossover_frequency: kCrossOverFrequencyHz,
61 low_pass_coefficients: &lo_pass_coefficients,
62 high_pass_coefficients: &hi_pass_coefficients);
63
64 // Create two biquad filters initialized with the above filter coefficients.
65 lo_pass_filter_.SetCoefficients(lo_pass_coefficients);
66 hi_pass_filter_.SetCoefficients(hi_pass_coefficients);
67}
68
69void NearFieldProcessor::Process(const AudioBuffer::Channel& input,
70 AudioBuffer::Channel* output,
71 bool enable_hrtf) {
72
73 DCHECK(output);
74 DCHECK_EQ(input.size(), frames_per_buffer_);
75 DCHECK_EQ(output->size(), frames_per_buffer_);
76
77 // Low-pass filter the input and put it in the temporary low-passed buffer.
78 auto* low_passed_channel = &low_passed_buffer_[0];
79 lo_pass_filter_.Filter(input_channel: input, output_channel: low_passed_channel);
80
81 // High-pass filter the input and put it in the output channel (unmodified).
82 hi_pass_filter_.Filter(input_channel: input, output_channel: output);
83 // Iterate through all the samples in the |low_passed_buffer_| and apply
84 // the bass boost. Then, combine with the high-passed part in order to form
85 // the shelf-filtered output. Note: phase flip of the low-passed signal is
86 // required to form the correct filtered output.
87 ConstantGain(/*offset_index=*/0, gain: -kBassBoost, input_samples: *low_passed_channel, output_samples: output,
88 /*accumulate_output=*/true);
89
90 if (enable_hrtf) {
91 // Delay the output to compensate for the average HRTF group delay.
92 delay_filter_.InsertData(input: *output);
93 delay_filter_.GetDelayedData(delay_samples: delay_compensation_, buffer: output);
94 }
95}
96
97} // namespace vraudio
98

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/dsp/near_field_processor.cc