1 /* 2 * Copyright (C) 2013 The Android Open Source Project 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 #ifndef LE_FX_ENGINE_DSP_CORE_DYNAMIC_RANGE_COMPRESSION_H_ 17 #define LE_FX_ENGINE_DSP_CORE_DYNAMIC_RANGE_COMPRESSION_H_ 18 19 //#define LOG_NDEBUG 0 20 21 #include "common/core/types.h" 22 #include "common/core/math.h" 23 #include "dsp/core/basic.h" 24 #include "dsp/core/interpolation.h" 25 26 #include <android/log.h> 27 28 namespace le_fx { 29 30 // An adaptive dynamic range compression algorithm. The gain adaptation is made 31 // at the logarithmic domain and it is based on a Branching-Smooth compensated 32 // digital peak detector with different time constants for attack and release. 33 class AdaptiveDynamicRangeCompression { 34 public: 35 AdaptiveDynamicRangeCompression(); 36 37 // Initializes the compressor using prior information. It assumes that the 38 // input signal is speech from high-quality recordings that is scaled and then 39 // fed to the compressor. The compressor is tuned according to the target gain 40 // that is expected to be applied. 41 // 42 // Target gain receives values between 0.0 and 10.0. The knee threshold is 43 // reduced as the target gain increases in order to fit the increased range of 44 // values. 45 // 46 // Values between 1.0 and 2.0 will only mildly affect your signal. Higher 47 // values will reduce the dynamic range of the signal to the benefit of 48 // increased loudness. 49 // 50 // If nothing is known regarding the input, a `target_gain` of 1.0f is a 51 // relatively safe choice for many signals. 52 bool Initialize(float target_gain, float sampling_rate); 53 54 // A fast version of the algorithm that uses approximate computations for the 55 // log(.) and exp(.). 56 float Compress(float x); 57 58 // Stereo channel version of the compressor 59 void Compress(float *x1, float *x2); 60 61 // This version is slower than Compress(.) but faster than CompressSlow(.) 62 float CompressNormalSpeed(float x); 63 64 // A slow version of the algorithm that is easier for further developement, 65 // tuning and debugging 66 float CompressSlow(float x); 67 68 // Sets knee threshold (in decibel). 69 void set_knee_threshold(float decibel); 70 71 // Sets knee threshold via the target gain using an experimentally derived 72 // relationship. 73 void set_knee_threshold_via_target_gain(float target_gain); 74 75 private: 76 // The minimum accepted absolute input value and it's natural logarithm. This 77 // is to prevent numerical issues when the input is close to zero 78 static const float kMinAbsValue; 79 static const float kMinLogAbsValue; 80 // Fixed-point arithmetic limits 81 static const float kFixedPointLimit; 82 static const float kInverseFixedPointLimit; 83 // The default knee threshold in decibel. The knee threshold defines when the 84 // compressor is actually starting to compress the value of the input samples 85 static const float kDefaultKneeThresholdInDecibel; 86 // The compression ratio is the reciprocal of the slope of the line segment 87 // above the threshold (in the log-domain). The ratio controls the 88 // effectiveness of the compression. 89 static const float kCompressionRatio; 90 // The attack time of the envelope detector 91 static const float kTauAttack; 92 // The release time of the envelope detector 93 static const float kTauRelease; 94 95 float sampling_rate_; 96 // the internal state of the envelope detector 97 float state_; 98 // the latest gain factor that was applied to the input signal 99 float compressor_gain_; 100 // attack constant for exponential dumping 101 float alpha_attack_; 102 // release constant for exponential dumping 103 float alpha_release_; 104 float slope_; 105 // The knee threshold 106 float knee_threshold_; 107 float knee_threshold_in_decibel_; 108 // This interpolator provides the function that relates target gain to knee 109 // threshold. 110 sigmod::InterpolatorLinear<float> target_gain_to_knee_threshold_; 111 112 LE_FX_DISALLOW_COPY_AND_ASSIGN(AdaptiveDynamicRangeCompression); 113 }; 114 115 } // namespace le_fx 116 117 #include "dsp/core/dynamic_range_compression-inl.h" 118 119 #endif // LE_FX_ENGINE_DSP_CORE_DYNAMIC_RANGE_COMPRESSION_H_ 120