| 1 | /* | 
| 2 | Copyright 2018 Google Inc. All Rights Reserved. | 
| 3 |  | 
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); | 
| 5 | you may not use this file except in compliance with the License. | 
| 6 | You may obtain a copy of the License at | 
| 7 |  | 
| 8 |     http://www.apache.org/licenses/LICENSE-2.0 | 
| 9 |  | 
| 10 | Unless required by applicable law or agreed to in writing, software | 
| 11 | distributed under the License is distributed on an "AS-IS" BASIS, | 
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
| 13 | See the License for the specific language governing permissions and | 
| 14 | limitations under the License. | 
| 15 | */ | 
| 16 |  | 
| 17 | #include "graph/gain_node.h" | 
| 18 |  | 
| 19 | #include <cmath> | 
| 20 |  | 
| 21 |  | 
| 22 | #include "dsp/gain.h" | 
| 23 |  | 
| 24 | namespace vraudio { | 
| 25 |  | 
| 26 | GainNode::GainNode(SourceId source_id, size_t num_channels, | 
| 27 |                    const AttenuationType& attenuation_type, | 
| 28 |                    const SystemSettings& system_settings) | 
| 29 |     : num_channels_(num_channels), | 
| 30 |       attenuation_type_(attenuation_type), | 
| 31 |       gain_processors_(num_channels_), | 
| 32 |       system_settings_(system_settings), | 
| 33 |       output_buffer_(num_channels, system_settings.GetFramesPerBuffer()) { | 
| 34 |   DCHECK_GT(num_channels, 0U); | 
| 35 |   output_buffer_.set_source_id(source_id); | 
| 36 | } | 
| 37 |  | 
| 38 | const AudioBuffer* GainNode::AudioProcess(const NodeInput& input) { | 
| 39 |  | 
| 40 |  | 
| 41 |   const AudioBuffer* input_buffer = input.GetSingleInput(); | 
| 42 |   DCHECK(input_buffer); | 
| 43 |   DCHECK_EQ(input_buffer->num_channels(), num_channels_); | 
| 44 |   DCHECK_EQ(input_buffer->source_id(), output_buffer_.source_id()); | 
| 45 |  | 
| 46 |   const auto source_parameters = | 
| 47 |       system_settings_.GetSourceParameters(source_id: input_buffer->source_id()); | 
| 48 |   if (source_parameters == nullptr) { | 
| 49 |     LOG(WARNING) << "Could not find source parameters" ; | 
| 50 |     return nullptr; | 
| 51 |   } | 
| 52 |  | 
| 53 |   const float current_gain = gain_processors_[0].GetGain(); | 
| 54 |   const float target_gain = source_parameters->attenuations[attenuation_type_]; | 
| 55 |   if (IsGainNearZero(gain: target_gain) && IsGainNearZero(gain: current_gain)) { | 
| 56 |     // Make sure the gain processors are initialized. | 
| 57 |     for (size_t i = 0; i < num_channels_; ++i) { | 
| 58 |       gain_processors_[i].Reset(gain: 0.0f); | 
| 59 |     } | 
| 60 |     // Skip processing in case of zero gain. | 
| 61 |     return nullptr; | 
| 62 |   } | 
| 63 |   if (IsGainNearUnity(gain: target_gain) && IsGainNearUnity(gain: current_gain)) { | 
| 64 |     // Make sure the gain processors are initialized. | 
| 65 |     for (size_t i = 0; i < num_channels_; ++i) { | 
| 66 |       gain_processors_[i].Reset(gain: 1.0f); | 
| 67 |     } | 
| 68 |     // Skip processing in case of unity gain. | 
| 69 |     return input_buffer; | 
| 70 |   } | 
| 71 |  | 
| 72 |   // Apply the gain to each input buffer channel. | 
| 73 |   for (size_t i = 0; i < num_channels_; ++i) { | 
| 74 |     gain_processors_[i].ApplyGain(target_gain, input: (*input_buffer)[i], | 
| 75 |                                   output: &output_buffer_[i], | 
| 76 |                                   accumulate_output: false /* accumulate_output */); | 
| 77 |   } | 
| 78 |  | 
| 79 |   return &output_buffer_; | 
| 80 | } | 
| 81 |  | 
| 82 | }  // namespace vraudio | 
| 83 |  |