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 "graph/ambisonic_binaural_decoder_node.h"
18
19#include "ambisonics/stereo_from_soundfield_converter.h"
20#include "ambisonics/utils.h"
21#include "base/constants_and_types.h"
22
23#include "dsp/sh_hrir_creator.h"
24
25namespace vraudio {
26
27AmbisonicBinauralDecoderNode::AmbisonicBinauralDecoderNode(
28 const SystemSettings& system_settings, int ambisonic_order,
29 const std::string& sh_hrir_filename, FftManager* fft_manager,
30 Resampler* resampler)
31 : system_settings_(system_settings),
32 num_ambisonic_channels_(GetNumPeriphonicComponents(ambisonic_order)),
33 is_stereo_speaker_mode_(system_settings_.IsStereoSpeakerModeEnabled()),
34 num_frames_processed_on_empty_input_(
35 system_settings_.GetFramesPerBuffer()),
36 stereo_output_buffer_(kNumStereoChannels,
37 system_settings.GetFramesPerBuffer()),
38 silence_input_buffer_(num_ambisonic_channels_,
39 system_settings.GetFramesPerBuffer()),
40 crossfader_(system_settings_.GetFramesPerBuffer()),
41 crossfaded_output_buffer_(kNumStereoChannels,
42 system_settings.GetFramesPerBuffer()),
43 temp_crossfade_buffer_(kNumStereoChannels,
44 system_settings.GetFramesPerBuffer()) {
45 silence_input_buffer_.Clear();
46 EnableProcessOnEmptyInput(enable: true);
47 std::unique_ptr<AudioBuffer> sh_hrirs = CreateShHrirsFromAssets(
48 filename: sh_hrir_filename, target_sample_rate_hz: system_settings_.GetSampleRateHz(), resampler);
49 CHECK_EQ(sh_hrirs->num_channels(), num_ambisonic_channels_);
50 ambisonic_binaural_decoder_.reset(p: new AmbisonicBinauralDecoder(
51 *sh_hrirs, system_settings_.GetFramesPerBuffer(), fft_manager));
52}
53
54AmbisonicBinauralDecoderNode::~AmbisonicBinauralDecoderNode() {}
55
56const AudioBuffer* AmbisonicBinauralDecoderNode::AudioProcess(
57 const NodeInput& input) {
58
59
60 const bool was_stereo_speaker_mode_enabled = is_stereo_speaker_mode_;
61 is_stereo_speaker_mode_ = system_settings_.IsStereoSpeakerModeEnabled();
62
63 const size_t num_frames = system_settings_.GetFramesPerBuffer();
64 const AudioBuffer* input_buffer = input.GetSingleInput();
65 if (input_buffer == nullptr) {
66 if (num_frames_processed_on_empty_input_ < num_frames &&
67 !was_stereo_speaker_mode_enabled) {
68 // If we have no input, generate a silent input buffer until the node
69 // states are cleared.
70 num_frames_processed_on_empty_input_ += num_frames;
71 ambisonic_binaural_decoder_->Process(input: silence_input_buffer_,
72 output: &stereo_output_buffer_);
73 return &stereo_output_buffer_;
74 } else {
75 // Skip processing entirely when the states are fully cleared.
76 return nullptr;
77 }
78 }
79
80 num_frames_processed_on_empty_input_ = 0;
81
82 DCHECK_EQ(input_buffer->num_channels(), num_ambisonic_channels_);
83 DCHECK_EQ(input_buffer->num_frames(), num_frames);
84
85 // If stereo speaker mode is enabled, perform M-S stereo decode. Otherwise,
86 // perform binaural decode.
87 if (is_stereo_speaker_mode_) {
88 StereoFromSoundfield(soundfield_input: *input_buffer, stereo_output: &stereo_output_buffer_);
89 } else {
90 ambisonic_binaural_decoder_->Process(input: *input_buffer, output: &stereo_output_buffer_);
91 }
92
93 if (is_stereo_speaker_mode_ != was_stereo_speaker_mode_enabled) {
94 // Apply linear crossfade between binaural decode and stereo decode outputs.
95 if (was_stereo_speaker_mode_enabled) {
96 StereoFromSoundfield(soundfield_input: *input_buffer, stereo_output: &temp_crossfade_buffer_);
97 } else {
98 ambisonic_binaural_decoder_->Process(input: *input_buffer,
99 output: &temp_crossfade_buffer_);
100 }
101 crossfader_.ApplyLinearCrossfade(input_fade_in: stereo_output_buffer_,
102 input_fade_out: temp_crossfade_buffer_,
103 output: &crossfaded_output_buffer_);
104 return &crossfaded_output_buffer_;
105 }
106
107 // Return the rendered output directly.
108 return &stereo_output_buffer_;
109}
110
111} // namespace vraudio
112

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/graph/ambisonic_binaural_decoder_node.cc