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

Side by Side Diff: third_party/WebKit/Source/platform/audio/DynamicsCompressorKernel.cpp

Issue 2384073002: reflow comments in platform/audio (Closed)
Patch Set: comments (heh!) Created 4 years, 2 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
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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 m_lastPreDelayFrames = preDelayFrames; 87 m_lastPreDelayFrames = preDelayFrames;
88 for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i) 88 for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i)
89 m_preDelayBuffers[i]->zero(); 89 m_preDelayBuffers[i]->zero();
90 90
91 m_preDelayReadIndex = 0; 91 m_preDelayReadIndex = 0;
92 m_preDelayWriteIndex = preDelayFrames; 92 m_preDelayWriteIndex = preDelayFrames;
93 } 93 }
94 } 94 }
95 95
96 // Exponential curve for the knee. 96 // Exponential curve for the knee.
97 // It is 1st derivative matched at m_linearThreshold and asymptotically approach es the value m_linearThreshold + 1 / k. 97 // It is 1st derivative matched at m_linearThreshold and asymptotically
98 // approaches the value m_linearThreshold + 1 / k.
98 float DynamicsCompressorKernel::kneeCurve(float x, float k) { 99 float DynamicsCompressorKernel::kneeCurve(float x, float k) {
99 // Linear up to threshold. 100 // Linear up to threshold.
100 if (x < m_linearThreshold) 101 if (x < m_linearThreshold)
101 return x; 102 return x;
102 103
103 return m_linearThreshold + (1 - expf(-k * (x - m_linearThreshold))) / k; 104 return m_linearThreshold + (1 - expf(-k * (x - m_linearThreshold))) / k;
104 } 105 }
105 106
106 // Full compression curve with constant ratio after knee. 107 // Full compression curve with constant ratio after knee.
107 float DynamicsCompressorKernel::saturate(float x, float k) { 108 float DynamicsCompressorKernel::saturate(float x, float k) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 float DynamicsCompressorKernel::kAtSlope(float desiredSlope) { 144 float DynamicsCompressorKernel::kAtSlope(float desiredSlope) {
144 float xDb = m_dbThreshold + m_dbKnee; 145 float xDb = m_dbThreshold + m_dbKnee;
145 float x = decibelsToLinear(xDb); 146 float x = decibelsToLinear(xDb);
146 147
147 // Approximate k given initial values. 148 // Approximate k given initial values.
148 float minK = 0.1; 149 float minK = 0.1;
149 float maxK = 10000; 150 float maxK = 10000;
150 float k = 5; 151 float k = 5;
151 152
152 for (int i = 0; i < 15; ++i) { 153 for (int i = 0; i < 15; ++i) {
153 // A high value for k will more quickly asymptotically approach a slope of 0 . 154 // A high value for k will more quickly asymptotically approach a slope of
155 // 0.
154 float slope = slopeAt(x, k); 156 float slope = slopeAt(x, k);
155 157
156 if (slope < desiredSlope) { 158 if (slope < desiredSlope) {
157 // k is too high. 159 // k is too high.
158 maxK = k; 160 maxK = k;
159 } else { 161 } else {
160 // k is too low. 162 // k is too low.
161 minK = k; 163 minK = k;
162 } 164 }
163 165
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 // Create a smooth function which passes through four points. 246 // Create a smooth function which passes through four points.
245 247
246 // Polynomial of the form 248 // Polynomial of the form
247 // y = a + b*x + c*x^2 + d*x^3 + e*x^4; 249 // y = a + b*x + c*x^2 + d*x^3 + e*x^4;
248 250
249 float y1 = releaseFrames * releaseZone1; 251 float y1 = releaseFrames * releaseZone1;
250 float y2 = releaseFrames * releaseZone2; 252 float y2 = releaseFrames * releaseZone2;
251 float y3 = releaseFrames * releaseZone3; 253 float y3 = releaseFrames * releaseZone3;
252 float y4 = releaseFrames * releaseZone4; 254 float y4 = releaseFrames * releaseZone4;
253 255
254 // All of these coefficients were derived for 4th order polynomial curve fitti ng where the y values 256 // All of these coefficients were derived for 4th order polynomial curve
255 // match the evenly spaced x values as follows: (y1 : x == 0, y2 : x == 1, y3 : x == 2, y4 : x == 3) 257 // fitting where the y values match the evenly spaced x values as follows:
258 // (y1 : x == 0, y2 : x == 1, y3 : x == 2, y4 : x == 3)
256 float a = 0.9999999999999998f * y1 + 1.8432219684323923e-16f * y2 - 259 float a = 0.9999999999999998f * y1 + 1.8432219684323923e-16f * y2 -
257 1.9373394351676423e-16f * y3 + 8.824516011816245e-18f * y4; 260 1.9373394351676423e-16f * y3 + 8.824516011816245e-18f * y4;
258 float b = -1.5788320352845888f * y1 + 2.3305837032074286f * y2 - 261 float b = -1.5788320352845888f * y1 + 2.3305837032074286f * y2 -
259 0.9141194204840429f * y3 + 0.1623677525612032f * y4; 262 0.9141194204840429f * y3 + 0.1623677525612032f * y4;
260 float c = 0.5334142869106424f * y1 - 1.272736789213631f * y2 + 263 float c = 0.5334142869106424f * y1 - 1.272736789213631f * y2 +
261 0.9258856042207512f * y3 - 0.18656310191776226f * y4; 264 0.9258856042207512f * y3 - 0.18656310191776226f * y4;
262 float d = 0.08783463138207234f * y1 - 0.1694162967925622f * y2 + 265 float d = 0.08783463138207234f * y1 - 0.1694162967925622f * y2 +
263 0.08588057951595272f * y3 - 0.00429891410546283f * y4; 266 0.08588057951595272f * y3 - 0.00429891410546283f * y4;
264 float e = -0.042416883008123074f * y1 + 0.1115693827987602f * y2 - 267 float e = -0.042416883008123074f * y1 + 0.1115693827987602f * y2 -
265 0.09764676325265872f * y3 + 0.028494263462021576f * y4; 268 0.09764676325265872f * y3 + 0.028494263462021576f * y4;
266 269
267 // x ranges from 0 -> 3 0 1 2 3 270 // x ranges from 0 -> 3 0 1 2 3
268 // -15 -10 -5 0db 271 // -15 -10 -5 0db
269 272
270 // y calculates adaptive release frames depending on the amount of compression . 273 // y calculates adaptive release frames depending on the amount of
274 // compression.
271 275
272 setPreDelayTime(preDelayTime); 276 setPreDelayTime(preDelayTime);
273 277
274 const int nDivisionFrames = 32; 278 const int nDivisionFrames = 32;
275 279
276 const int nDivisions = framesToProcess / nDivisionFrames; 280 const int nDivisions = framesToProcess / nDivisionFrames;
277 281
278 unsigned frameIndex = 0; 282 unsigned frameIndex = 0;
279 for (int i = 0; i < nDivisions; ++i) { 283 for (int i = 0; i < nDivisions; ++i) {
280 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ 284 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
281 // Calculate desired gain 285 // Calculate desired gain
282 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ 286 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
283 287
284 // Fix gremlins. 288 // Fix gremlins.
285 if (std::isnan(m_detectorAverage)) 289 if (std::isnan(m_detectorAverage))
286 m_detectorAverage = 1; 290 m_detectorAverage = 1;
287 if (std::isinf(m_detectorAverage)) 291 if (std::isinf(m_detectorAverage))
288 m_detectorAverage = 1; 292 m_detectorAverage = 1;
289 293
290 float desiredGain = m_detectorAverage; 294 float desiredGain = m_detectorAverage;
291 295
292 // Pre-warp so we get desiredGain after sin() warp below. 296 // Pre-warp so we get desiredGain after sin() warp below.
293 float scaledDesiredGain = asinf(desiredGain) / (piOverTwoFloat); 297 float scaledDesiredGain = asinf(desiredGain) / (piOverTwoFloat);
294 298
295 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ 299 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
296 // Deal with envelopes 300 // Deal with envelopes
297 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ 301 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
298 302
299 // envelopeRate is the rate we slew from current compressor level to the des ired level. 303 // envelopeRate is the rate we slew from current compressor level to the
300 // The exact rate depends on if we're attacking or releasing and by how much . 304 // desired level. The exact rate depends on if we're attacking or
305 // releasing and by how much.
301 float envelopeRate; 306 float envelopeRate;
302 307
303 bool isReleasing = scaledDesiredGain > m_compressorGain; 308 bool isReleasing = scaledDesiredGain > m_compressorGain;
304 309
305 // compressionDiffDb is the difference between current compression level and the desired level. 310 // compressionDiffDb is the difference between current compression level and
311 // the desired level.
306 float compressionDiffDb = 312 float compressionDiffDb =
307 linearToDecibels(m_compressorGain / scaledDesiredGain); 313 linearToDecibels(m_compressorGain / scaledDesiredGain);
308 314
309 if (isReleasing) { 315 if (isReleasing) {
310 // Release mode - compressionDiffDb should be negative dB 316 // Release mode - compressionDiffDb should be negative dB
311 m_maxAttackCompressionDiffDb = -1; 317 m_maxAttackCompressionDiffDb = -1;
312 318
313 // Fix gremlins. 319 // Fix gremlins.
314 if (std::isnan(compressionDiffDb)) 320 if (std::isnan(compressionDiffDb))
315 compressionDiffDb = -1; 321 compressionDiffDb = -1;
316 if (std::isinf(compressionDiffDb)) 322 if (std::isinf(compressionDiffDb))
317 compressionDiffDb = -1; 323 compressionDiffDb = -1;
318 324
319 // Adaptive release - higher compression (lower compressionDiffDb) releas es faster. 325 // Adaptive release - higher compression (lower compressionDiffDb)
326 // releases faster.
320 327
321 // Contain within range: -12 -> 0 then scale to go from 0 -> 3 328 // Contain within range: -12 -> 0 then scale to go from 0 -> 3
322 float x = compressionDiffDb; 329 float x = compressionDiffDb;
323 x = clampTo(x, -12.0f, 0.0f); 330 x = clampTo(x, -12.0f, 0.0f);
324 x = 0.25f * (x + 12); 331 x = 0.25f * (x + 12);
325 332
326 // Compute adaptive release curve using 4th order polynomial. 333 // Compute adaptive release curve using 4th order polynomial.
327 // Normal values for the polynomial coefficients would create a monotonica lly increasing function. 334 // Normal values for the polynomial coefficients would create a
335 // monotonically increasing function.
328 float x2 = x * x; 336 float x2 = x * x;
329 float x3 = x2 * x; 337 float x3 = x2 * x;
330 float x4 = x2 * x2; 338 float x4 = x2 * x2;
331 float releaseFrames = a + b * x + c * x2 + d * x3 + e * x4; 339 float releaseFrames = a + b * x + c * x2 + d * x3 + e * x4;
332 340
333 #define kSpacingDb 5 341 #define kSpacingDb 5
334 float dbPerFrame = kSpacingDb / releaseFrames; 342 float dbPerFrame = kSpacingDb / releaseFrames;
335 343
336 envelopeRate = decibelsToLinear(dbPerFrame); 344 envelopeRate = decibelsToLinear(dbPerFrame);
337 } else { 345 } else {
(...skipping 24 matching lines...) Expand all
362 { 370 {
363 int preDelayReadIndex = m_preDelayReadIndex; 371 int preDelayReadIndex = m_preDelayReadIndex;
364 int preDelayWriteIndex = m_preDelayWriteIndex; 372 int preDelayWriteIndex = m_preDelayWriteIndex;
365 float detectorAverage = m_detectorAverage; 373 float detectorAverage = m_detectorAverage;
366 float compressorGain = m_compressorGain; 374 float compressorGain = m_compressorGain;
367 375
368 int loopFrames = nDivisionFrames; 376 int loopFrames = nDivisionFrames;
369 while (loopFrames--) { 377 while (loopFrames--) {
370 float compressorInput = 0; 378 float compressorInput = 0;
371 379
372 // Predelay signal, computing compression amount from un-delayed version . 380 // Predelay signal, computing compression amount from un-delayed
381 // version.
373 for (unsigned i = 0; i < numberOfChannels; ++i) { 382 for (unsigned i = 0; i < numberOfChannels; ++i) {
374 float* delayBuffer = m_preDelayBuffers[i]->data(); 383 float* delayBuffer = m_preDelayBuffers[i]->data();
375 float undelayedSource = sourceChannels[i][frameIndex]; 384 float undelayedSource = sourceChannels[i][frameIndex];
376 delayBuffer[preDelayWriteIndex] = undelayedSource; 385 delayBuffer[preDelayWriteIndex] = undelayedSource;
377 386
378 float absUndelayedSource = 387 float absUndelayedSource =
379 undelayedSource > 0 ? undelayedSource : -undelayedSource; 388 undelayedSource > 0 ? undelayedSource : -undelayedSource;
380 if (compressorInput < absUndelayedSource) 389 if (compressorInput < absUndelayedSource)
381 compressorInput = absUndelayedSource; 390 compressorInput = absUndelayedSource;
382 } 391 }
383 392
384 // Calculate shaped power on undelayed input. 393 // Calculate shaped power on undelayed input.
385 394
386 float scaledInput = compressorInput; 395 float scaledInput = compressorInput;
387 float absInput = scaledInput > 0 ? scaledInput : -scaledInput; 396 float absInput = scaledInput > 0 ? scaledInput : -scaledInput;
388 397
389 // Put through shaping curve. 398 // Put through shaping curve.
390 // This is linear up to the threshold, then enters a "knee" portion foll owed by the "ratio" portion. 399 // This is linear up to the threshold, then enters a "knee" portion
391 // The transition from the threshold to the knee is smooth (1st derivati ve matched). 400 // followed by the "ratio" portion. The transition from the threshold
392 // The transition from the knee to the ratio portion is smooth (1st deri vative matched). 401 // to the knee is smooth (1st derivative matched). The transition from
402 // the knee to the ratio portion is smooth (1st derivative matched).
393 float shapedInput = saturate(absInput, k); 403 float shapedInput = saturate(absInput, k);
394 404
395 float attenuation = absInput <= 0.0001f ? 1 : shapedInput / absInput; 405 float attenuation = absInput <= 0.0001f ? 1 : shapedInput / absInput;
396 406
397 float attenuationDb = -linearToDecibels(attenuation); 407 float attenuationDb = -linearToDecibels(attenuation);
398 attenuationDb = std::max(2.0f, attenuationDb); 408 attenuationDb = std::max(2.0f, attenuationDb);
399 409
400 float dbPerFrame = attenuationDb / satReleaseFrames; 410 float dbPerFrame = attenuationDb / satReleaseFrames;
401 411
402 float satReleaseRate = decibelsToLinear(dbPerFrame) - 1; 412 float satReleaseRate = decibelsToLinear(dbPerFrame) - 1;
(...skipping 13 matching lines...) Expand all
416 // Exponential approach to desired gain. 426 // Exponential approach to desired gain.
417 if (envelopeRate < 1) { 427 if (envelopeRate < 1) {
418 // Attack - reduce gain to desired. 428 // Attack - reduce gain to desired.
419 compressorGain += (scaledDesiredGain - compressorGain) * envelopeRate; 429 compressorGain += (scaledDesiredGain - compressorGain) * envelopeRate;
420 } else { 430 } else {
421 // Release - exponentially increase gain to 1.0 431 // Release - exponentially increase gain to 1.0
422 compressorGain *= envelopeRate; 432 compressorGain *= envelopeRate;
423 compressorGain = std::min(1.0f, compressorGain); 433 compressorGain = std::min(1.0f, compressorGain);
424 } 434 }
425 435
426 // Warp pre-compression gain to smooth out sharp exponential transition points. 436 // Warp pre-compression gain to smooth out sharp exponential transition
437 // points.
427 float postWarpCompressorGain = sinf(piOverTwoFloat * compressorGain); 438 float postWarpCompressorGain = sinf(piOverTwoFloat * compressorGain);
428 439
429 // Calculate total gain using master gain and effect blend. 440 // Calculate total gain using master gain and effect blend.
430 float totalGain = 441 float totalGain =
431 dryMix + wetMix * masterLinearGain * postWarpCompressorGain; 442 dryMix + wetMix * masterLinearGain * postWarpCompressorGain;
432 443
433 // Calculate metering. 444 // Calculate metering.
434 float dbRealGain = 20 * std::log10(postWarpCompressorGain); 445 float dbRealGain = 20 * std::log10(postWarpCompressorGain);
435 if (dbRealGain < m_meteringGain) 446 if (dbRealGain < m_meteringGain)
436 m_meteringGain = dbRealGain; 447 m_meteringGain = dbRealGain;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i) 480 for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i)
470 m_preDelayBuffers[i]->zero(); 481 m_preDelayBuffers[i]->zero();
471 482
472 m_preDelayReadIndex = 0; 483 m_preDelayReadIndex = 0;
473 m_preDelayWriteIndex = DefaultPreDelayFrames; 484 m_preDelayWriteIndex = DefaultPreDelayFrames;
474 485
475 m_maxAttackCompressionDiffDb = -1; // uninitialized state 486 m_maxAttackCompressionDiffDb = -1; // uninitialized state
476 } 487 }
477 488
478 } // namespace blink 489 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698