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