Bela
Real-time, ultra-low-latency audio and sensor processing system for BeagleBone Black
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
EnvelopeDetector.h
1 #pragma once
2 #include <math.h>
3 /*
4  * \brief Envelope Detector Class.
5  * This detector uses one-pole IIR filters to extract the approximate envelope of an audio signal.
6  * Different modes of operation have been implemented to simulate detectors commonly used in compressors and other audio effects.
7  *
8  * Learn more:
9  * * Reiss, J. D., & McPherson, A. (2014). Audio effects: theory, implementation and application. CRC Press.
10  * * Pirkle, W. C. (2019). Designing Audio Effect Plugins in C++: For AAX, AU, and VST3 with DSP Theory. Routledge.
11  * * Giannoulis, D., Massberg, M., & Reiss, J. D. (2012). Digital dynamic range compressor design tutorial and analysis. Journal of the Audio Engineering Society, 60(6), 399-408.
12  *
13  * October 2021
14  * author: Adan L. Benito
15  */
16 
18 {
19  public:
20  const float kTcAnalog = log(1/M_E);
21  const float kTcDigital= log(0.01);
22 
23  /*
24  * Type of time constant employed by envelope detector
25  */
26  typedef enum {
27  ANALOG = 0, /* < analog */
28  DIGITAL = 1 /* < digital */
29  } ConstantMode;
30 
31  /*
32  * Type of peak detection strategy followed by the peak detector
33  */
34  typedef enum {
35  DECOUPLING = 0, /* < decoupling: detector with instantaneous attack filtered for release */
36  BRANCHING = 1 /* < branching: separated branches for attack and release */
37  } BranchingMode;
38 
39  /*
40  * Type of level detection strategy employed to provide a smooth representation of signal's level
41  */
42  typedef enum {
43  PEAK = 0, /* < peak: detection performed over absolute peak values of the signal */
44  MS = 1, /* < mean square values of the input are used for detection */
45  RMS = 2, /* < root mean square values of the input are used for detecton */
46  PREPROCESSED = 3 /* < raw input is used for detection, assumes that a processed signal is feed into the detector */
47  } DetectionMode;
48 
50  /*
51  * Initialise envelope detector.
52  *
53  * @param attackTimeMs Attack time in milliseconds.
54  * @param releaseTimeMs Release time in milliseconds
55  * @param sampleRate Sampling frequency.
56  * @param constantMode Type of time constant employed by the detector
57  * @param branchingMode Type of peak detection strategy (branching or decoupling)
58  * @param detectionMode Type of level detection strategy
59  * @param smooth Boolean value indicating whether to use smooth release or not
60  */
61  EnvelopeDetector(float attackTimeMs, float releaseTimeMs, float sampleRate, unsigned int constantMode = ANALOG, unsigned int branchingMode = BRANCHING, unsigned int detectionMode = PEAK, bool smooth = true);
63  /*
64  * \copydoc EnvelopeDetector::EnvelopeDetector(float, float, float, unsigned int, unsigned int, unsigned int, bool)
65  *
66  * @return 0 upon success, error otherwise
67  */
68  int setup(float attackTimeMs, float releaseTimeMs, float sampleRate, unsigned int constantMode = ANALOG, unsigned int branchingMode = BRANCHING, unsigned int detectionMode = PEAK, bool smooth = true);
69  int cleanup();
70 
71  /*
72  * Process input signal acording to detector's parameters and return envelope.
73  *
74  * @return Computed envelope
75  */
76  float process(float input);
77  /*
78  * Set attack time
79  *
80  * @param attackTimeMs Attack time (milliseconds)
81  */
82  void setAttackTime(float attackTimeMs);
83  /*
84  * Get attack time
85  *
86  * @returns Attack time in milliseconds
87  */
88  float getAttackTime() { return _attackTimeMs; };
89  /*
90  * Set release time
91  *
92  * @param releaseTimeMs Release time (milliseconds)
93  */
94  void setReleaseTime(float releaseTimeMs);
95  /*
96  * Get release time
97  *
98  * @returns Release time in milliseconds
99  */
100  float getReleaseTime() { return _releaseTimeMs; };
101  /*
102  * Set mode of operation for time constant
103  *
104  * @param mode Mode of operation for time constant (\see EnvelopeDetector::ConstantMode)
105  */
106  void setConstantMode(unsigned int mode);
107  /*
108  * Get time constant mode of operation
109  */
110  unsigned int getConstantMode() { return _constantMode; };
111  /*
112  * Set branching mode
113  *
114  * @param mode Branching mode (\see EnvelopeDetector::BranchingMode)
115  */
116  void setBranchingMode(unsigned int mode);
117  /*
118  * Get branching mode
119  */
120  unsigned int getBranchingMOde() { return _branchingMode; };
121  /*
122  * Set envelope detection mode
123  *
124  * @param mode Detection mode (\see EnvelopeDetector::DetectionMode)
125  */
126  void setDetectionMode(unsigned int mode);
127  /*
128  * Get envelope detection mode
129  */
130  unsigned getDetectionMode() { return _detectionMode; };
131 
132  /*
133  * Set smooth release operation for detector
134  *
135  * @param isSmooth Boolean, if true then use smooth release.
136  */
137  void setSmooth(bool isSmooth);
138  /*
139  * Retrieve whether smooth operation is being used or not
140  */
141  bool getSmooth() { return _smooth; };
142 
143  private:
144  float _fs = 0.0; // Sampling frequency
145  float _tc = kTcAnalog; // Time contstant
146 
147  float _attackTimeMs = 0.0; // Attack time in milliseconds
148  float _releaseTimeMs = 0.0; // Release time in milliseconds
149 
150  float _tConstantAttack = 0.0; // Attack time constant
151  float _tConstantRelease = 0.0; // Release time constant
152 
153  float _fastPeakEstimation = 0.0; // Only for DECOUPLING detector
154  float _envelope = 0.0; // Envelope value
155 
156  unsigned int _constantMode = ANALOG; // Time constant mode
157  unsigned int _branchingMode = BRANCHING; // Branching mode
158  unsigned int _detectionMode = PEAK; // Detection mode
159 
160  bool _smooth = true; // Flag for smooth operation
161 
162  /*
163  * Compute time constant for given time in milliseconds
164  *
165  * @param timeMs Time in milliseconds
166  */
167  double computeTimeConstant(float timeMs);
168  /*
169  * Reset detector state
170  */
171  void resetState();
172 };
Definition: EnvelopeDetector.h:17