swift
SimpleCompProcess.inl
1 /*
2  * Simple Compressor (runtime function)
3  *
4  * File : SimpleCompProcess.inl
5  * Library : SimpleSource
6  * Version : 1.12
7  * Implements : void SimpleComp::process( double &in1, double &in2 )
8  * void SimpleComp::process( double &in1, double &in2, double keyLinked )
9  * void SimpleCompRms::process( double &in1, double &in2 )
10  *
11  * © 2006, ChunkWare Music Software, OPEN-SOURCE
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in
21  * all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  */
31 
32 
33 #ifndef __SIMPLE_COMP_PROCESS_INL__
34 #define __SIMPLE_COMP_PROCESS_INL__
35 
36 namespace chunkware_simple
37 {
38  //-------------------------------------------------------------
39  INLINE void SimpleComp::process( double &in1, double &in2 )
40  {
41  // create sidechain
42 
43  double rect1 = fabs( in1 ); // rectify input
44  double rect2 = fabs( in2 );
45 
46  /* if desired, one could use another EnvelopeDetector to smooth
47  * the rectified signal.
48  */
49 
50  double link = std::max( rect1, rect2 ); // link channels with greater of 2
51 
52  process( in1, in2, link ); // rest of process
53  }
54 
55  //-------------------------------------------------------------
56  INLINE void SimpleComp::process( double &in1, double &in2, double keyLinked )
57  {
58  keyLinked = fabs( keyLinked ); // rectify (just in case)
59 
60  // convert key to dB
61  keyLinked += DC_OFFSET; // add DC offset to avoid log( 0 )
62  double keydB = lin2dB( keyLinked ); // convert linear -> dB
63 
64  // threshold
65  double overdB = keydB - threshdB_; // delta over threshold
66  if ( overdB < 0.0 )
67  overdB = 0.0;
68 
69  // attack/release
70 
71  overdB += DC_OFFSET; // add DC offset to avoid denormal
72  AttRelEnvelope::run( overdB, envdB_ ); // run attack/release envelope
73  overdB = envdB_ - DC_OFFSET; // subtract DC offset
74 
75  /* REGARDING THE DC OFFSET: In this case, since the offset is added before
76  * the attack/release processes, the envelope will never fall below the offset,
77  * thereby avoiding denormals. However, to prevent the offset from causing
78  * constant gain reduction, we must subtract it from the envelope, yielding
79  * a minimum value of 0dB.
80  */
81 
82  // transfer function
83  double gr = overdB * ( ratio_ - 1.0 ); // gain reduction (dB)
84  gr = dB2lin( gr ) * dB2lin( makeUpGain_ ); // convert dB -> linear
85 
86  // output gain
87  in1 *= gr; // apply gain reduction to input
88  in2 *= gr;
89  }
90 
91  //-------------------------------------------------------------
92  INLINE void SimpleCompRms::process( double &in1, double &in2 )
93  {
94  // create sidechain
95 
96  double inSq1 = in1 * in1; // square input
97  double inSq2 = in2 * in2;
98 
99  double sum = inSq1 + inSq2; // power summing
100  sum += DC_OFFSET; // DC offset, to prevent denormal
101  ave_.run( sum, aveOfSqrs_ ); // average of squares
102  double rms = sqrt( aveOfSqrs_ ); // rms (sort of ...)
103 
104  /* REGARDING THE RMS AVERAGER: Ok, so this isn't a REAL RMS
105  * calculation. A true RMS is an FIR moving average. This
106  * approximation is a 1-pole IIR. Nonetheless, in practice,
107  * and in the interest of simplicity, this method will suffice,
108  * giving comparable results.
109  */
110 
111  SimpleComp::process( in1, in2, rms ); // rest of process
112  }
113 
114 } // end namespace chunkware_simple
115 
116 #endif // end __SIMPLE_COMP_PROCESS_INL__
INLINE void run(double in, double &state)
Runtime function.
INLINE void run(double in, double &state)
runtime function
void process(double &in1, double &in2)
compressor runtime process
void process(double &in1, double &in2)
Runtime process.