dynamic_range_compression.h revision 6cc3a9948b51193dfdcb0c3527d7f3d1ca38aa3c
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#include "common/core/types.h" 20#include "common/core/math.h" 21#include "dsp/core/basic.h" 22#include "dsp/core/interpolation.h" 23 24//#define LOG_NDEBUG 0 25#include <cutils/log.h> 26 27 28namespace 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. 33class 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 // This version is slower than Compress(.) but faster than CompressSlow(.) 59 float CompressNormalSpeed(float x); 60 61 // A slow version of the algorithm that is easier for further developement, 62 // tuning and debugging 63 float CompressSlow(float x); 64 65 // Sets knee threshold (in decibel). 66 void set_knee_threshold(float decibel); 67 68 // Sets knee threshold via the target gain using an experimentally derived 69 // relationship. 70 void set_knee_threshold_via_target_gain(float target_gain); 71 72 private: 73 // The minimum accepted absolute input value and it's natural logarithm. This 74 // is to prevent numerical issues when the input is close to zero 75 static const float kMinAbsValue; 76 static const float kMinLogAbsValue; 77 // Fixed-point arithmetic limits 78 static const float kFixedPointLimit; 79 static const float kInverseFixedPointLimit; 80 // The default knee threshold in decibel. The knee threshold defines when the 81 // compressor is actually starting to compress the value of the input samples 82 static const float kDefaultKneeThresholdInDecibel; 83 // The compression ratio is the reciprocal of the slope of the line segment 84 // above the threshold (in the log-domain). The ratio controls the 85 // effectiveness of the compression. 86 static const float kCompressionRatio; 87 // The attack time of the envelope detector 88 static const float kTauAttack; 89 // The release time of the envelope detector 90 static const float kTauRelease; 91 92 float sampling_rate_; 93 // the internal state of the envelope detector 94 float state_; 95 // the latest gain factor that was applied to the input signal 96 float compressor_gain_; 97 // attack constant for exponential dumping 98 float alpha_attack_; 99 // release constant for exponential dumping 100 float alpha_release_; 101 float slope_; 102 // The knee threshold 103 float knee_threshold_; 104 float knee_threshold_in_decibel_; 105 // This interpolator provides the function that relates target gain to knee 106 // threshold. 107 sigmod::InterpolatorLinear<float> target_gain_to_knee_threshold_; 108 109 LE_FX_DISALLOW_COPY_AND_ASSIGN(AdaptiveDynamicRangeCompression); 110}; 111 112} // namespace le_fx 113 114#include "dsp/core/dynamic_range_compression-inl.h" 115 116#endif // LE_FX_ENGINE_DSP_CORE_DYNAMIC_RANGE_COMPRESSION_H_ 117