1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 /* Copyright (C) 2011 Google Inc. All rights reserved.
7  * Use of this source code is governed by a BSD-style license that can be
8  * found in the LICENSE.WEBKIT file.
9  */
10 
11 #ifndef DRC_H_
12 #define DRC_H_
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 #include "crossover2.h"
19 #include "drc_kernel.h"
20 #include "eq2.h"
21 
22 /* DRC implements a flexible audio dynamics compression effect such as is
23  * commonly used in musical production and game audio. It lowers the volume of
24  * the loudest parts of the signal and raises the volume of the softest parts,
25  * making the sound richer, fuller, and more controlled.
26  *
27  * This is a three band stereo DRC. There are three compressor kernels, and each
28  * can have its own parameters. If a kernel is disabled, it only delays the
29  * signal and does not compress it.
30  *
31  *                   INPUT
32  *                     |
33  *                +----------+
34  *                | emphasis |
35  *                +----------+
36  *                     |
37  *               +------------+
38  *               | crossover  |
39  *               +------------+
40  *               /     |      \
41  *      (low band) (mid band) (high band)
42  *             /       |        \
43  *         +------+ +------+ +------+
44  *         |  drc | |  drc | |  drc |
45  *         |kernel| |kernel| |kernel|
46  *         +------+ +------+ +------+
47  *              \      |        /
48  *               \     |       /
49  *              +-------------+
50  *              |     (+)     |
51  *              +-------------+
52  *                     |
53  *              +------------+
54  *              | deemphasis |
55  *              +------------+
56  *                     |
57  *                   OUTPUT
58  *
59  */
60 
61 /* The parameters of the DRC compressor.
62  *
63  * PARAM_THRESHOLD - The value above which the compression starts, in dB.
64  * PARAM_KNEE - The value above which the knee region starts, in dB.
65  * PARAM_RATIO - The input/output dB ratio after the knee region.
66  * PARAM_ATTACK - The time to reduce the gain by 10dB, in seconds.
67  * PARAM_RELEASE - The time to increase the gain by 10dB, in seconds.
68  * PARAM_PRE_DELAY - The lookahead time for the compressor, in seconds.
69  * PARAM_RELEASE_ZONE[1-4] - The adaptive release curve parameters.
70  * PARAM_POST_GAIN - The static boost value in output, in dB.
71  * PARAM_FILTER_STAGE_GAIN - The gain of each emphasis filter stage.
72  * PARAM_FILTER_STAGE_RATIO - The frequency ratio for each emphasis filter stage
73  *     to the previous stage.
74  * PARAM_FILTER_ANCHOR - The frequency of the first emphasis filter, in
75  *     normalized frequency (in [0, 1], relative to half of the sample rate).
76  * PARAM_CROSSOVER_LOWER_FREQ - The lower frequency of the band, in normalized
77  *     frequency (in [0, 1], relative to half of the sample rate).
78  * PARAM_ENABLED - 1 to enable the compressor, 0 to disable it.
79  */
80 enum {
81 	PARAM_THRESHOLD,
82 	PARAM_KNEE,
83 	PARAM_RATIO,
84 	PARAM_ATTACK,
85 	PARAM_RELEASE,
86 	PARAM_PRE_DELAY,
87 	PARAM_RELEASE_ZONE1,
88 	PARAM_RELEASE_ZONE2,
89 	PARAM_RELEASE_ZONE3,
90 	PARAM_RELEASE_ZONE4,
91 	PARAM_POST_GAIN,
92 	PARAM_FILTER_STAGE_GAIN,
93 	PARAM_FILTER_STAGE_RATIO,
94 	PARAM_FILTER_ANCHOR,
95 	PARAM_CROSSOVER_LOWER_FREQ,
96 	PARAM_ENABLED,
97 	PARAM_LAST
98 };
99 
100 /* The number of compressor kernels (also the number of bands). */
101 #define DRC_NUM_KERNELS 3
102 
103 /* The maximum number of frames can be passed to drc_process() call. */
104 #define DRC_PROCESS_MAX_FRAMES 2048
105 
106 /* The default value of PARAM_PRE_DELAY in seconds. */
107 #define DRC_DEFAULT_PRE_DELAY 0.006f
108 
109 struct drc {
110 	/* sample rate in Hz */
111 	float sample_rate;
112 
113 	/* 1 to disable the emphasis and deemphasis, 0 to enable it. */
114 	int emphasis_disabled;
115 
116 	/* parameters holds the tweakable compressor parameters. */
117 	float parameters[DRC_NUM_KERNELS][PARAM_LAST];
118 
119 	/* The emphasis filter and deemphasis filter */
120 	struct eq2 *emphasis_eq;
121 	struct eq2 *deemphasis_eq;
122 
123 	/* The crossover filter */
124 	struct crossover2 xo2;
125 
126 	/* The compressor kernels */
127 	struct drc_kernel kernel[DRC_NUM_KERNELS];
128 
129 	/* Temporary buffer used during drc_process(). The mid and high band
130 	 * signal is stored in these buffers (the low band is stored in the
131 	 * original input buffer). */
132 	float *data1[DRC_NUM_CHANNELS];
133 	float *data2[DRC_NUM_CHANNELS];
134 };
135 
136 /* DRC needs the parameters to be set before initialization. So drc_new() should
137  * be called first to allocated an instance, then drc_set_param() is called
138  * (multiple times) to set the parameters. Finally drc_init() is called to do
139  * the initialization. After that drc_process() can be used to process data. The
140  * sequence is:
141  *
142  *  drc_new();
143  *  drc_set_param();
144  *  ...
145  *  drc_set_param();
146  *  drc_init();
147  *  drc_process();
148  *  ...
149  *  drc_process();
150  *  drc_free();
151  */
152 
153 /* Allocates a DRC. */
154 struct drc *drc_new(float sample_rate);
155 
156 /* Initializes a DRC. */
157 void drc_init(struct drc *drc);
158 
159 /* Frees a DRC.*/
160 void drc_free(struct drc *drc);
161 
162 /* Processes input data using a DRC.
163  * Args:
164  *    drc - The DRC we want to use.
165  *    float **data - Pointers to input/output data. The input must be stereo
166  *        and one channel is pointed by data[0], another pointed by data[1]. The
167  *        output data is stored in the same place.
168  *    frames - The number of frames to process.
169  */
170 void drc_process(struct drc *drc, float **data, int frames);
171 
172 /* Sets a parameter for the DRC.
173  * Args:
174  *    drc - The DRC we want to use.
175  *    index - The index of the kernel we want to set its parameter.
176  *    paramID - One of the PARAM_* enum constant.
177  *    value - The parameter value
178  */
179 void drc_set_param(struct drc *drc, int index, unsigned paramID, float value);
180 
181 #ifdef __cplusplus
182 } /* extern "C" */
183 #endif
184 
185 #endif /* DRC_H_ */
186