Changeset 102888 in webkit


Ignore:
Timestamp:
Dec 14, 2011 10:14:11 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

fast path to accelerate processing in AudioBus::processWithGainFromMonoStereo
https://bugs.webkit.org/show_bug.cgi?id=74054

Patch by Wei James <james.wei@intel.com> on 2011-12-14
Reviewed by Kenneth Russell.

Avoid de-zippering when the gain has converged on the targetGain.
It can get about 75% performance gain at most when all frames don't need
de-zippering.

  • platform/audio/AudioBus.cpp:

(WebCore::AudioBus::processWithGainFromMonoStereo):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r102882 r102888  
     12011-12-14  Wei James  <james.wei@intel.com>
     2
     3        fast path to accelerate processing in AudioBus::processWithGainFromMonoStereo
     4        https://bugs.webkit.org/show_bug.cgi?id=74054
     5
     6        Reviewed by Kenneth Russell.
     7
     8        Avoid de-zippering when the gain has converged on the targetGain.
     9        It can get about 75% performance gain at most when all frames don't need
     10        de-zippering.
     11
     12        * platform/audio/AudioBus.cpp:
     13        (WebCore::AudioBus::processWithGainFromMonoStereo):
     14
    1152011-12-14  Adam Klein  <adamk@chromium.org>
    216
  • trunk/Source/WebCore/platform/audio/AudioBus.cpp

    r102702 r102888  
    232232}
    233233
     234// Slowly change gain to desired gain.
     235#define GAIN_DEZIPPER \
     236    gain += (totalDesiredGain - gain) * DezipperRate; \
     237    gain = DenormalDisabler::flushDenormalFloatToZero(gain);
     238
     239// De-zipper for the first framesToDezipper frames and skip de-zippering for the remaining frames
     240// because the gain is close enough to the target gain.
     241#define PROCESS_WITH_GAIN(OP) \
     242    for (k = 0; k < framesToDezipper; ++k) { \
     243        OP \
     244        GAIN_DEZIPPER \
     245    } \
     246    gain = totalDesiredGain; \
     247    for (; k < framesToProcess; ++k)  \
     248        OP
     249
     250#define STEREO_SUM \
     251    { \
     252        float sumL = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++); \
     253        float sumR = DenormalDisabler::flushDenormalFloatToZero(*destinationR + gain * *sourceR++); \
     254        *destinationL++ = sumL; \
     255        *destinationR++ = sumR; \
     256    }
     257
     258// Mono -> stereo (mix equally into L and R)
     259// FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
     260#define MONO2STEREO_SUM \
     261    { \
     262        float scaled = gain * *sourceL++; \
     263        float sumL = DenormalDisabler::flushDenormalFloatToZero(*destinationL + scaled); \
     264        float sumR = DenormalDisabler::flushDenormalFloatToZero(*destinationR + scaled); \
     265        *destinationL++ = sumL; \
     266        *destinationR++ = sumR; \
     267    }
     268
     269#define MONO_SUM \
     270    { \
     271        float sum = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++); \
     272        *destinationL++ = sum; \
     273    }
     274
     275#define STEREO_NO_SUM \
     276    { \
     277        float sampleL = *sourceL++; \
     278        float sampleR = *sourceR++; \
     279        *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL); \
     280        *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleR); \
     281    }
     282
     283// Mono -> stereo (mix equally into L and R)
     284// FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
     285#define MONO2STEREO_NO_SUM \
     286    { \
     287        float sample = *sourceL++; \
     288        *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample); \
     289        *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample); \
     290    }
     291
     292#define MONO_NO_SUM \
     293    { \
     294        float sampleL = *sourceL++; \
     295        *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL); \
     296    }
     297
    234298void AudioBus::processWithGainFromMonoStereo(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus)
    235299{
     
    238302
    239303    // FIXME: optimize this method (SSE, etc.)
    240     // FIXME: Need fast path here when gain has converged on targetGain. In this case, de-zippering is no longer needed.
    241     // FIXME: Need fast path when this==sourceBus && lastMixGain==targetGain==1.0 && sumToBus==false (this is a NOP)
    242 
    243304    // FIXME: targetGain and lastMixGain should be changed to floats instead of doubles.
    244305   
     
    263324    int framesToProcess = length();
    264325
     326    // If the gain is within epsilon of totalDesiredGain, we can skip dezippering.
     327    // FIXME: this value may need tweaking.
     328    const float epsilon = 0.001f;
     329    float gainDiff = fabs(totalDesiredGain - gain);
     330
     331    // Number of frames to de-zipper before we are close enough to the target gain.
     332    int framesToDezipper = (gainDiff < epsilon) ? 0 : framesToProcess;
     333
     334    int k = 0;
     335
    265336    if (sumToBus) {
    266337        // Sum to our bus
    267338        if (sourceR && destinationR) {
    268339            // Stereo
    269             while (framesToProcess--) {
    270                 float sumL = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++);
    271                 float sumR = DenormalDisabler::flushDenormalFloatToZero(*destinationR + gain * *sourceR++);
    272                 *destinationL++ = sumL;
    273                 *destinationR++ = sumR;
    274 
    275                 // Slowly change gain to desired gain.
    276                 gain += (totalDesiredGain - gain) * DezipperRate;
    277                 gain = DenormalDisabler::flushDenormalFloatToZero(gain);
    278             }
     340            PROCESS_WITH_GAIN(STEREO_SUM)
    279341        } else if (destinationR) {
    280             // Mono -> stereo (mix equally into L and R)
    281             // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
    282             while (framesToProcess--) {
    283                 float scaled = gain * *sourceL++;
    284                 float sumL = DenormalDisabler::flushDenormalFloatToZero(*destinationL + scaled);
    285                 float sumR = DenormalDisabler::flushDenormalFloatToZero(*destinationR + scaled);
    286 
    287                 *destinationL++ = sumL;
    288                 *destinationR++ = sumR;
    289 
    290                 // Slowly change gain to desired gain.
    291                 gain += (totalDesiredGain - gain) * DezipperRate;
    292                 gain = DenormalDisabler::flushDenormalFloatToZero(gain);
    293             }
     342            // Mono -> stereo
     343            PROCESS_WITH_GAIN(MONO2STEREO_SUM)
    294344        } else {
    295345            // Mono
    296             while (framesToProcess--) {
    297                 float sum = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++);
    298                 *destinationL++ = sum;
    299 
    300                 // Slowly change gain to desired gain.
    301                 gain += (totalDesiredGain - gain) * DezipperRate;
    302                 gain = DenormalDisabler::flushDenormalFloatToZero(gain);
    303             }
     346            PROCESS_WITH_GAIN(MONO_SUM)
    304347        }
    305348    } else {
    306349        // Process directly (without summing) to our bus
     350        // If it is from the same bus and no need to change gain, just return
     351        if (this == &sourceBus && *lastMixGain == targetGain && targetGain == 1.0)
     352            return;
     353
     354        // FIXME: if (framesToDezipper == 0) and DenormalDisabler::flushDenormalFloatToZero() is a NOP (gcc vs. Visual Studio)
     355        // then we can further optimize the PROCESS_WITH_GAIN codepaths below using vsmul().
    307356        if (sourceR && destinationR) {
    308357            // Stereo
    309             while (framesToProcess--) {
    310                 float sampleL = *sourceL++;
    311                 float sampleR = *sourceR++;
    312                 *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL);
    313                 *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleR);
    314 
    315                 // Slowly change gain to desired gain.
    316                 gain += (totalDesiredGain - gain) * DezipperRate;
    317                 gain = DenormalDisabler::flushDenormalFloatToZero(gain);
    318             }
     358            PROCESS_WITH_GAIN(STEREO_NO_SUM)
    319359        } else if (destinationR) {
    320             // Mono -> stereo (mix equally into L and R)
    321             // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
    322             while (framesToProcess--) {
    323                 float sample = *sourceL++;
    324                 *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample);
    325                 *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample);
    326 
    327                 // Slowly change gain to desired gain.
    328                 gain += (totalDesiredGain - gain) * DezipperRate;
    329                 gain = DenormalDisabler::flushDenormalFloatToZero(gain);
    330             }
     360            // Mono -> stereo
     361            PROCESS_WITH_GAIN(MONO2STEREO_NO_SUM)
    331362        } else {
    332363            // Mono
    333             while (framesToProcess--) {
    334                 float sampleL = *sourceL++;
    335                 *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL);
    336 
    337                 // Slowly change gain to desired gain.
    338                 gain += (totalDesiredGain - gain) * DezipperRate;
    339                 gain = DenormalDisabler::flushDenormalFloatToZero(gain);
    340             }
     364            PROCESS_WITH_GAIN(MONO_NO_SUM)
    341365        }
    342366    }
Note: See TracChangeset for help on using the changeset viewer.