Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: Source/platform/audio/DynamicsCompressor.cpp

Issue 152333003: Remove emphasis/de-emphasis filters from DynamicsCompressor. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Add expected result. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Linear crossfade (0 -> 1). 88 // Linear crossfade (0 -> 1).
89 m_parameters[ParamEffectBlend] = 1; 89 m_parameters[ParamEffectBlend] = 1;
90 } 90 }
91 91
92 float DynamicsCompressor::parameterValue(unsigned parameterID) 92 float DynamicsCompressor::parameterValue(unsigned parameterID)
93 { 93 {
94 ASSERT(parameterID < ParamLast); 94 ASSERT(parameterID < ParamLast);
95 return m_parameters[parameterID]; 95 return m_parameters[parameterID];
96 } 96 }
97 97
98 void DynamicsCompressor::setEmphasisStageParameters(unsigned stageIndex, float g ain, float normalizedFrequency /* 0 -> 1 */)
99 {
100 float gk = 1 - gain / 20;
101 float f1 = normalizedFrequency * gk;
102 float f2 = normalizedFrequency / gk;
103 float r1 = expf(-f1 * piFloat);
104 float r2 = expf(-f2 * piFloat);
105
106 ASSERT(m_numberOfChannels == m_preFilterPacks.size());
107
108 for (unsigned i = 0; i < m_numberOfChannels; ++i) {
109 // Set pre-filter zero and pole to create an emphasis filter.
110 ZeroPole& preFilter = m_preFilterPacks[i]->filters[stageIndex];
111 preFilter.setZero(r1);
112 preFilter.setPole(r2);
113
114 // Set post-filter with zero and pole reversed to create the de-emphasis filter.
115 // If there were no compressor kernel in between, they would cancel each other out (allpass filter).
116 ZeroPole& postFilter = m_postFilterPacks[i]->filters[stageIndex];
117 postFilter.setZero(r2);
118 postFilter.setPole(r1);
119 }
120 }
121
122 void DynamicsCompressor::setEmphasisParameters(float gain, float anchorFreq, flo at filterStageRatio)
123 {
124 setEmphasisStageParameters(0, gain, anchorFreq);
125 setEmphasisStageParameters(1, gain, anchorFreq / filterStageRatio);
126 setEmphasisStageParameters(2, gain, anchorFreq / (filterStageRatio * filterS tageRatio));
127 setEmphasisStageParameters(3, gain, anchorFreq / (filterStageRatio * filterS tageRatio * filterStageRatio));
128 }
129
130 void DynamicsCompressor::process(const AudioBus* sourceBus, AudioBus* destinatio nBus, unsigned framesToProcess) 98 void DynamicsCompressor::process(const AudioBus* sourceBus, AudioBus* destinatio nBus, unsigned framesToProcess)
131 { 99 {
132 // Though numberOfChannels is retrived from destinationBus, we still name it numberOfChannels instead of numberOfDestinationChannels. 100 // Though numberOfChannels is retrived from destinationBus, we still name it numberOfChannels instead of numberOfDestinationChannels.
133 // It's because we internally match sourceChannels's size to destinationBus by channel up/down mix. Thus we need numberOfChannels 101 // It's because we internally match sourceChannels's size to destinationBus by channel up/down mix. Thus we need numberOfChannels
134 // to do the loop work for both m_sourceChannels and m_destinationChannels. 102 // to do the loop work for both m_sourceChannels and m_destinationChannels.
135 103
136 unsigned numberOfChannels = destinationBus->numberOfChannels(); 104 unsigned numberOfChannels = destinationBus->numberOfChannels();
137 unsigned numberOfSourceChannels = sourceBus->numberOfChannels(); 105 unsigned numberOfSourceChannels = sourceBus->numberOfChannels();
138 106
139 ASSERT(numberOfChannels == m_numberOfChannels && numberOfSourceChannels); 107 ASSERT(numberOfChannels == m_numberOfChannels && numberOfSourceChannels);
(...skipping 26 matching lines...) Expand all
166 134
167 float filterStageGain = parameterValue(ParamFilterStageGain); 135 float filterStageGain = parameterValue(ParamFilterStageGain);
168 float filterStageRatio = parameterValue(ParamFilterStageRatio); 136 float filterStageRatio = parameterValue(ParamFilterStageRatio);
169 float anchor = parameterValue(ParamFilterAnchor); 137 float anchor = parameterValue(ParamFilterAnchor);
170 138
171 if (filterStageGain != m_lastFilterStageGain || filterStageRatio != m_lastFi lterStageRatio || anchor != m_lastAnchor) { 139 if (filterStageGain != m_lastFilterStageGain || filterStageRatio != m_lastFi lterStageRatio || anchor != m_lastAnchor) {
172 m_lastFilterStageGain = filterStageGain; 140 m_lastFilterStageGain = filterStageGain;
173 m_lastFilterStageRatio = filterStageRatio; 141 m_lastFilterStageRatio = filterStageRatio;
174 m_lastAnchor = anchor; 142 m_lastAnchor = anchor;
175 143
176 setEmphasisParameters(filterStageGain, anchor, filterStageRatio);
177 }
178
179 // Apply pre-emphasis filter.
180 // Note that the final three stages are computed in-place in the destination buffer.
181 for (unsigned i = 0; i < numberOfChannels; ++i) {
182 const float* sourceData = m_sourceChannels[i];
183 float* destinationData = m_destinationChannels[i];
184 ZeroPole* preFilters = m_preFilterPacks[i]->filters;
185
186 preFilters[0].process(sourceData, destinationData, framesToProcess);
187 preFilters[1].process(destinationData, destinationData, framesToProcess) ;
188 preFilters[2].process(destinationData, destinationData, framesToProcess) ;
189 preFilters[3].process(destinationData, destinationData, framesToProcess) ;
190 } 144 }
191 145
192 float dbThreshold = parameterValue(ParamThreshold); 146 float dbThreshold = parameterValue(ParamThreshold);
193 float dbKnee = parameterValue(ParamKnee); 147 float dbKnee = parameterValue(ParamKnee);
194 float ratio = parameterValue(ParamRatio); 148 float ratio = parameterValue(ParamRatio);
195 float attackTime = parameterValue(ParamAttack); 149 float attackTime = parameterValue(ParamAttack);
196 float releaseTime = parameterValue(ParamRelease); 150 float releaseTime = parameterValue(ParamRelease);
197 float preDelayTime = parameterValue(ParamPreDelay); 151 float preDelayTime = parameterValue(ParamPreDelay);
198 152
199 // This is effectively a master volume on the compressed signal (pre-blendin g). 153 // This is effectively a master volume on the compressed signal (pre-blendin g).
200 float dbPostGain = parameterValue(ParamPostGain); 154 float dbPostGain = parameterValue(ParamPostGain);
201 155
202 // Linear blending value from dry to completely processed (0 -> 1) 156 // Linear blending value from dry to completely processed (0 -> 1)
203 // 0 means the signal is completely unprocessed. 157 // 0 means the signal is completely unprocessed.
204 // 1 mixes in only the compressed signal. 158 // 1 mixes in only the compressed signal.
205 float effectBlend = parameterValue(ParamEffectBlend); 159 float effectBlend = parameterValue(ParamEffectBlend);
206 160
207 float releaseZone1 = parameterValue(ParamReleaseZone1); 161 float releaseZone1 = parameterValue(ParamReleaseZone1);
208 float releaseZone2 = parameterValue(ParamReleaseZone2); 162 float releaseZone2 = parameterValue(ParamReleaseZone2);
209 float releaseZone3 = parameterValue(ParamReleaseZone3); 163 float releaseZone3 = parameterValue(ParamReleaseZone3);
210 float releaseZone4 = parameterValue(ParamReleaseZone4); 164 float releaseZone4 = parameterValue(ParamReleaseZone4);
211 165
212 // Apply compression to the pre-filtered signal. 166 // Apply compression to the source signal.
213 // The processing is performed in place. 167 m_compressor.process(m_sourceChannels.get(),
214 m_compressor.process(m_destinationChannels.get(),
215 m_destinationChannels.get(), 168 m_destinationChannels.get(),
216 numberOfChannels, 169 numberOfChannels,
217 framesToProcess, 170 framesToProcess,
218 171
219 dbThreshold, 172 dbThreshold,
220 dbKnee, 173 dbKnee,
221 ratio, 174 ratio,
222 attackTime, 175 attackTime,
223 releaseTime, 176 releaseTime,
224 preDelayTime, 177 preDelayTime,
225 dbPostGain, 178 dbPostGain,
226 effectBlend, 179 effectBlend,
227 180
228 releaseZone1, 181 releaseZone1,
229 releaseZone2, 182 releaseZone2,
230 releaseZone3, 183 releaseZone3,
231 releaseZone4 184 releaseZone4
232 ); 185 );
233 186
234 // Update the compression amount. 187 // Update the compression amount.
235 setParameterValue(ParamReduction, m_compressor.meteringGain()); 188 setParameterValue(ParamReduction, m_compressor.meteringGain());
236 189
237 // Apply de-emphasis filter.
238 for (unsigned i = 0; i < numberOfChannels; ++i) {
239 float* destinationData = m_destinationChannels[i];
240 ZeroPole* postFilters = m_postFilterPacks[i]->filters;
241
242 postFilters[0].process(destinationData, destinationData, framesToProcess );
243 postFilters[1].process(destinationData, destinationData, framesToProcess );
244 postFilters[2].process(destinationData, destinationData, framesToProcess );
245 postFilters[3].process(destinationData, destinationData, framesToProcess );
246 }
247 } 190 }
248 191
249 void DynamicsCompressor::reset() 192 void DynamicsCompressor::reset()
250 { 193 {
251 m_lastFilterStageRatio = -1; // for recalc 194 m_lastFilterStageRatio = -1; // for recalc
252 m_lastAnchor = -1; 195 m_lastAnchor = -1;
253 m_lastFilterStageGain = -1; 196 m_lastFilterStageGain = -1;
254 197
255 for (unsigned channel = 0; channel < m_numberOfChannels; ++channel) {
256 for (unsigned stageIndex = 0; stageIndex < 4; ++stageIndex) {
257 m_preFilterPacks[channel]->filters[stageIndex].reset();
258 m_postFilterPacks[channel]->filters[stageIndex].reset();
259 }
260 }
261
262 m_compressor.reset(); 198 m_compressor.reset();
263 } 199 }
264 200
265 void DynamicsCompressor::setNumberOfChannels(unsigned numberOfChannels) 201 void DynamicsCompressor::setNumberOfChannels(unsigned numberOfChannels)
266 { 202 {
267 if (m_preFilterPacks.size() == numberOfChannels)
268 return;
269
270 m_preFilterPacks.clear();
271 m_postFilterPacks.clear();
272 for (unsigned i = 0; i < numberOfChannels; ++i) {
273 m_preFilterPacks.append(adoptPtr(new ZeroPoleFilterPack4()));
274 m_postFilterPacks.append(adoptPtr(new ZeroPoleFilterPack4()));
275 }
276
277 m_sourceChannels = adoptArrayPtr(new const float* [numberOfChannels]); 203 m_sourceChannels = adoptArrayPtr(new const float* [numberOfChannels]);
278 m_destinationChannels = adoptArrayPtr(new float* [numberOfChannels]); 204 m_destinationChannels = adoptArrayPtr(new float* [numberOfChannels]);
279 205
280 m_compressor.setNumberOfChannels(numberOfChannels); 206 m_compressor.setNumberOfChannels(numberOfChannels);
281 m_numberOfChannels = numberOfChannels; 207 m_numberOfChannels = numberOfChannels;
282 } 208 }
283 209
284 } // namespace WebCore 210 } // namespace WebCore
285 211
286 #endif // ENABLE(WEB_AUDIO) 212 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/platform/audio/DynamicsCompressor.h ('k') | Source/platform/audio/DynamicsCompressorKernel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698