Bug 1240054 - Only rebuild BandLimitedTables if more partials are required r=padenot a=sylvestre
authorDan Minor <dminor@mozilla.com>
Mon, 18 Jan 2016 08:51:29 -0500
changeset 310924 5e13efb1f0b8e9f8263c7dbdb752cff6507b4c4c
parent 310923 8e913ace1e198c34423bfadc807296f6400078bd
child 310925 481ff8485da5dbf3a712b9d2b534c76758d1d226
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot, sylvestre
bugs1240054
milestone45.0a2
Bug 1240054 - Only rebuild BandLimitedTables if more partials are required r=padenot a=sylvestre We currently rebuild the BandLimitedTables whenever we encounter a lower fundamental frequency but it is only necessary to rebuild the tables if we can fit more partials below the Nyquist frequency. Rebuilding the tables unnecessarily can cause performance problems, particularly in the case where the frequency is continually lowered.
dom/media/webaudio/blink/PeriodicWave.cpp
dom/media/webaudio/blink/PeriodicWave.h
--- a/dom/media/webaudio/blink/PeriodicWave.cpp
+++ b/dom/media/webaudio/blink/PeriodicWave.cpp
@@ -104,17 +104,18 @@ PeriodicWave::createTriangle(float sampl
         new PeriodicWave(sampleRate, MinPeriodicWaveSize);
     periodicWave->generateBasicWaveform(OscillatorType::Triangle);
     return periodicWave.forget();
 }
 
 PeriodicWave::PeriodicWave(float sampleRate, size_t numberOfComponents)
     : m_sampleRate(sampleRate)
     , m_centsPerRange(CentsPerRange)
-    , m_lowestRequestedFundamentalFrequency(std::numeric_limits<float>::max())
+    , m_maxPartialsInBandLimitedTable(0)
+    , m_normalizationScale(1.0f)
 {
     float nyquist = 0.5 * m_sampleRate;
 
     if (numberOfComponents <= MinPeriodicWaveSize) {
         m_periodicWaveSize = MinPeriodicWaveSize;
     } else {
         unsigned npow2 = powf(2.0f, floorf(logf(numberOfComponents - 1.0)/logf(2.0f) + 1.0f));
         m_periodicWaveSize = std::min(MaxPeriodicWaveSize, npow2);
@@ -142,25 +143,31 @@ size_t PeriodicWave::sizeOfIncludingThis
 
 void PeriodicWave::waveDataForFundamentalFrequency(float fundamentalFrequency, float* &lowerWaveData, float* &higherWaveData, float& tableInterpolationFactor)
 {
 
     // Negative frequencies are allowed, in which case we alias
     // to the positive frequency.
     fundamentalFrequency = fabsf(fundamentalFrequency);
 
-    if (fundamentalFrequency < m_lowestRequestedFundamentalFrequency) {
+    // We only need to rebuild to the tables if the new fundamental
+    // frequency is low enough to allow for more partials below the
+    // Nyquist frequency.
+    unsigned numberOfPartials = numberOfPartialsForRange(0);
+    float nyquist = 0.5 * m_sampleRate;
+    numberOfPartials = std::min(numberOfPartials, (unsigned)(nyquist / fundamentalFrequency));
+    if (numberOfPartials > m_maxPartialsInBandLimitedTable) {
         for (unsigned rangeIndex = 0; rangeIndex < m_numberOfRanges; ++rangeIndex) {
             m_bandLimitedTables[rangeIndex] = 0;
         }
 
         // We need to create the first table to determine the normalization
         // constant.
         createBandLimitedTables(fundamentalFrequency, 0);
-        m_lowestRequestedFundamentalFrequency = fundamentalFrequency;
+        m_maxPartialsInBandLimitedTable = numberOfPartials;
     }
 
     // Calculate the pitch range.
     float ratio = fundamentalFrequency > 0 ? fundamentalFrequency / m_lowestFundamentalFrequency : 0.5;
     float centsAboveLowestFrequency = logf(ratio)/logf(2.0f) * 1200;
 
     // Add one to round-up to the next range just in time to truncate
     // partials before aliasing occurs.
--- a/dom/media/webaudio/blink/PeriodicWave.h
+++ b/dom/media/webaudio/blink/PeriodicWave.h
@@ -101,16 +101,16 @@ private:
 
     // Maximum possible number of partials (before culling).
     unsigned maxNumberOfPartials() const;
 
     unsigned numberOfPartialsForRange(unsigned rangeIndex) const;
 
     // Creates table for specified index based on fundamental frequency.
     void createBandLimitedTables(float fundamentalFrequency, unsigned rangeIndex);
-    float m_lowestRequestedFundamentalFrequency;
+    unsigned m_maxPartialsInBandLimitedTable;
     float m_normalizationScale;
     nsTArray<nsAutoPtr<AlignedAudioFloatArray> > m_bandLimitedTables;
 };
 
 } // namespace WebCore
 
 #endif // PeriodicWave_h