b=865241 Add Blink's HRTFElevation to the build r=ehsan
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 08 Aug 2013 21:38:30 +1200
changeset 153775 581e1a7c6a7f92cb4d4f9786426e7604677b467c
parent 153774 4839aa086dfc864ef7d7c3f3048297716095acf5
child 153776 a867ee21d619a885d5aa8cce589092b70549237b
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs865241
milestone25.0a2
b=865241 Add Blink's HRTFElevation to the build r=ehsan (transplanted from 395fc5b9593cc2376f536012dc55e868c34164b5)
content/media/webaudio/blink/HRTFElevation.cpp
content/media/webaudio/blink/HRTFElevation.h
content/media/webaudio/blink/moz.build
--- a/content/media/webaudio/blink/HRTFElevation.cpp
+++ b/content/media/webaudio/blink/HRTFElevation.cpp
@@ -21,32 +21,21 @@
  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "config.h"
-
-#if ENABLE(WEB_AUDIO)
-
-#include "core/platform/audio/HRTFElevation.h"
+#include "HRTFElevation.h"
 
 #include "speex/speex_resampler.h"
 #include "mozilla/PodOperations.h"
 #include "AudioSampleFormat.h"
-#include <math.h>
-#include <algorithm>
-#include "core/platform/PlatformMemoryInstrumentation.h"
-#include "core/platform/audio/AudioBus.h"
-#include "core/platform/audio/HRTFPanner.h"
-#include <wtf/MemoryInstrumentationVector.h>
-#include <wtf/OwnPtr.h>
 
 #include "IRC_Composite_C_R0195-incl.cpp"
 
 using namespace std;
 using namespace mozilla;
  
 namespace WebCore {
 
@@ -89,18 +78,17 @@ size_t HRTFElevation::fftSizeForSampleRa
     size |= (size >> 2);
     size |= (size >> 4);
     size++;
     MOZ_ASSERT((size & (size - 1)) == 0);
 
     return size;
 }
 
-bool HRTFElevation::calculateKernelForAzimuthElevation(int azimuth, int elevation, SpeexResamplerState* resampler, float sampleRate,
-                                                       RefPtr<HRTFKernel>& kernelL)
+nsReturnRef<HRTFKernel> HRTFElevation::calculateKernelForAzimuthElevation(int azimuth, int elevation, SpeexResamplerState* resampler, float sampleRate)
 {
     int elevationIndex = (elevation - firstElevation) / elevationSpacing;
     MOZ_ASSERT(elevationIndex >= 0 && elevationIndex <= numberOfElevations);
 
     int numberOfAzimuths = irc_composite_c_r0195[elevationIndex].count;
     int azimuthSpacing = 360 / numberOfAzimuths;
     MOZ_ASSERT(numberOfAzimuths * azimuthSpacing == 360);
 
@@ -149,19 +137,17 @@ bool HRTFElevation::calculateKernelForAz
             // There may be some uninitialized samples remaining for very low
             // sample rates.
             PodZero(response + out_index, resampled.Length() - out_index);
         }
 
         speex_resampler_reset_mem(resampler);
     }
 
-    kernelL = HRTFKernel::create(response, responseLength, sampleRate);
-    
-    return true;
+    return HRTFKernel::create(response, responseLength, sampleRate);
 }
 
 // The range of elevations for the IRCAM impulse responses varies depending on azimuth, but the minimum elevation appears to always be -45.
 //
 // Here's how it goes:
 static int maxElevations[] = {
         //  Azimuth
         //
@@ -186,136 +172,126 @@ static int maxElevations[] = {
     60, // 270 
     45, // 285 
     75, // 300 
     45, // 315 
     60, // 330 
     45 //  345 
 };
 
-PassOwnPtr<HRTFElevation> HRTFElevation::createForSubject(const String& subjectName, int elevation, float sampleRate)
+nsReturnRef<HRTFElevation> HRTFElevation::createBuiltin(int elevation, float sampleRate)
 {
     if (elevation < firstElevation ||
         elevation > firstElevation + numberOfElevations * elevationSpacing ||
         (elevation / elevationSpacing) * elevationSpacing != elevation)
-        return nullptr;
+        return nsReturnRef<HRTFElevation>();
         
     // Spacing, in degrees, between every azimuth loaded from resource.
     // Some elevations do not have data for all these intervals.
     // See maxElevations.
     static const unsigned AzimuthSpacing = 15;
     static const unsigned NumberOfRawAzimuths = 360 / AzimuthSpacing;
     static_assert(AzimuthSpacing * NumberOfRawAzimuths == 360,
                   "Not a multiple");
     static const unsigned InterpolationFactor =
         NumberOfTotalAzimuths / NumberOfRawAzimuths;
     static_assert(NumberOfTotalAzimuths ==
                   NumberOfRawAzimuths * InterpolationFactor, "Not a multiple");
 
-    OwnPtr<HRTFKernelList> kernelListL = adoptPtr(new HRTFKernelList(NumberOfTotalAzimuths));
+    HRTFKernelList kernelListL;
+    kernelListL.SetLength(NumberOfTotalAzimuths);
 
     SpeexResamplerState* resampler = sampleRate == rawSampleRate ? nullptr :
         speex_resampler_init(1, rawSampleRate, sampleRate,
                              SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
 
     // Load convolution kernels from HRTF files.
     int interpolatedIndex = 0;
     for (unsigned rawIndex = 0; rawIndex < NumberOfRawAzimuths; ++rawIndex) {
         // Don't let elevation exceed maximum for this azimuth.
         int maxElevation = maxElevations[rawIndex];
         int actualElevation = min(elevation, maxElevation);
 
-        bool success = calculateKernelForAzimuthElevation(rawIndex * AzimuthSpacing, actualElevation, resampler, sampleRate, kernelListL->at(interpolatedIndex));
-        if (!success)
-            return nullptr;
+        kernelListL[interpolatedIndex] = calculateKernelForAzimuthElevation(rawIndex * AzimuthSpacing, actualElevation, resampler, sampleRate);
             
         interpolatedIndex += InterpolationFactor;
     }
 
     if (resampler)
         speex_resampler_destroy(resampler);
 
     // Now go back and interpolate intermediate azimuth values.
     for (unsigned i = 0; i < NumberOfTotalAzimuths; i += InterpolationFactor) {
         int j = (i + InterpolationFactor) % NumberOfTotalAzimuths;
 
         // Create the interpolated convolution kernels and delays.
         for (unsigned jj = 1; jj < InterpolationFactor; ++jj) {
             float x = float(jj) / float(InterpolationFactor); // interpolate from 0 -> 1
 
-            (*kernelListL)[i + jj] = HRTFKernel::createInterpolatedKernel(kernelListL->at(i).get(), kernelListL->at(j).get(), x);
+            kernelListL[i + jj] = HRTFKernel::createInterpolatedKernel(kernelListL[i], kernelListL[j], x);
         }
     }
     
-    OwnPtr<HRTFElevation> hrtfElevation = adoptPtr(new HRTFElevation(kernelListL.release(), elevation, sampleRate));
-    return hrtfElevation.release();
+    return nsReturnRef<HRTFElevation>(new HRTFElevation(&kernelListL, elevation, sampleRate));
 }
 
-PassOwnPtr<HRTFElevation> HRTFElevation::createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate)
+nsReturnRef<HRTFElevation> HRTFElevation::createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate)
 {
-    ASSERT(hrtfElevation1 && hrtfElevation2);
+    MOZ_ASSERT(hrtfElevation1 && hrtfElevation2);
     if (!hrtfElevation1 || !hrtfElevation2)
-        return nullptr;
+        return nsReturnRef<HRTFElevation>();
         
-    ASSERT(x >= 0.0 && x < 1.0);
+    MOZ_ASSERT(x >= 0.0 && x < 1.0);
     
-    OwnPtr<HRTFKernelList> kernelListL = adoptPtr(new HRTFKernelList(NumberOfTotalAzimuths));
+    HRTFKernelList kernelListL;
+    kernelListL.SetLength(NumberOfTotalAzimuths);
 
-    HRTFKernelList* kernelListL1 = hrtfElevation1->kernelListL();
-    HRTFKernelList* kernelListL2 = hrtfElevation2->kernelListL();
+    const HRTFKernelList& kernelListL1 = hrtfElevation1->kernelListL();
+    const HRTFKernelList& kernelListL2 = hrtfElevation2->kernelListL();
     
     // Interpolate kernels of corresponding azimuths of the two elevations.
     for (unsigned i = 0; i < NumberOfTotalAzimuths; ++i) {
-        (*kernelListL)[i] = HRTFKernel::createInterpolatedKernel(kernelListL1->at(i).get(), kernelListL2->at(i).get(), x);
+        kernelListL[i] = HRTFKernel::createInterpolatedKernel(kernelListL1[i], kernelListL2[i], x);
     }
 
     // Interpolate elevation angle.
     double angle = (1.0 - x) * hrtfElevation1->elevationAngle() + x * hrtfElevation2->elevationAngle();
     
-    OwnPtr<HRTFElevation> hrtfElevation = adoptPtr(new HRTFElevation(kernelListL.release(), static_cast<int>(angle), sampleRate));
-    return hrtfElevation.release();  
+    return nsReturnRef<HRTFElevation>(new HRTFElevation(&kernelListL, static_cast<int>(angle), sampleRate));
 }
 
 void HRTFElevation::getKernelsFromAzimuth(double azimuthBlend, unsigned azimuthIndex, HRTFKernel* &kernelL, HRTFKernel* &kernelR, double& frameDelayL, double& frameDelayR)
 {
     bool checkAzimuthBlend = azimuthBlend >= 0.0 && azimuthBlend < 1.0;
-    ASSERT(checkAzimuthBlend);
+    MOZ_ASSERT(checkAzimuthBlend);
     if (!checkAzimuthBlend)
         azimuthBlend = 0.0;
     
-    unsigned numKernels = m_kernelListL->size();
+    unsigned numKernels = m_kernelListL.Length();
 
     bool isIndexGood = azimuthIndex < numKernels;
-    ASSERT(isIndexGood);
+    MOZ_ASSERT(isIndexGood);
     if (!isIndexGood) {
         kernelL = 0;
         kernelR = 0;
         return;
     }
     
     // Return the left and right kernels,
     // using symmetry to produce the right kernel.
-    kernelL = m_kernelListL->at(azimuthIndex).get();
+    kernelL = m_kernelListL[azimuthIndex];
     int azimuthIndexR = (numKernels - azimuthIndex) % numKernels;
-    kernelR = m_kernelListL->at(azimuthIndexR).get();
+    kernelR = m_kernelListL[azimuthIndexR];
 
     frameDelayL = kernelL->frameDelay();
     frameDelayR = kernelR->frameDelay();
 
     int azimuthIndex2L = (azimuthIndex + 1) % numKernels;
-    double frameDelay2L = m_kernelListL->at(azimuthIndex2L)->frameDelay();
+    double frameDelay2L = m_kernelListL[azimuthIndex2L]->frameDelay();
     int azimuthIndex2R = (numKernels - azimuthIndex2L) % numKernels;
-    double frameDelay2R = m_kernelListL->at(azimuthIndex2R)->frameDelay();
+    double frameDelay2R = m_kernelListL[azimuthIndex2R]->frameDelay();
 
     // Linearly interpolate delays.
     frameDelayL = (1.0 - azimuthBlend) * frameDelayL + azimuthBlend * frameDelay2L;
     frameDelayR = (1.0 - azimuthBlend) * frameDelayR + azimuthBlend * frameDelay2R;
 }
 
-void HRTFElevation::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
-{
-    MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::AudioSharedData);
-    info.addMember(m_kernelListL, "kernelListL");
-}
-
 } // namespace WebCore
-
-#endif // ENABLE(WEB_AUDIO)
--- a/content/media/webaudio/blink/HRTFElevation.h
+++ b/content/media/webaudio/blink/HRTFElevation.h
@@ -24,77 +24,77 @@
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef HRTFElevation_h
 #define HRTFElevation_h
 
-#include "core/platform/audio/HRTFKernel.h"
-#include <wtf/Noncopyable.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
+#include "HRTFKernel.h"
+#include "nsAutoRef.h"
 
 struct SpeexResamplerState_;
 typedef struct SpeexResamplerState_ SpeexResamplerState;
 
 namespace WebCore {
 
 // HRTFElevation contains all of the HRTFKernels (one left ear and one right ear per azimuth angle) for a particular elevation.
 
 class HRTFElevation {
-    WTF_MAKE_NONCOPYABLE(HRTFElevation);
 public:
     // Loads and returns an HRTFElevation with the given HRTF database subject name and elevation from browser (or WebKit.framework) resources.
     // Normally, there will only be a single HRTF database set, but this API supports the possibility of multiple ones with different names.
     // Interpolated azimuths will be generated based on InterpolationFactor.
     // Valid values for elevation are -45 -> +90 in 15 degree increments.
-    static PassOwnPtr<HRTFElevation> createForSubject(const String& subjectName, int elevation, float sampleRate);
+    static nsReturnRef<HRTFElevation> createBuiltin(int elevation, float sampleRate);
 
     // Given two HRTFElevations, and an interpolation factor x: 0 -> 1, returns an interpolated HRTFElevation.
-    static PassOwnPtr<HRTFElevation> createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate);
+    static nsReturnRef<HRTFElevation> createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate);
 
     double elevationAngle() const { return m_elevationAngle; }
     unsigned numberOfAzimuths() const { return NumberOfTotalAzimuths; }
     float sampleRate() const { return m_sampleRate; }
     
     // Returns the left and right kernels for the given azimuth index.
     // The interpolated delays based on azimuthBlend: 0 -> 1 are returned in frameDelayL and frameDelayR.
     void getKernelsFromAzimuth(double azimuthBlend, unsigned azimuthIndex, HRTFKernel* &kernelL, HRTFKernel* &kernelR, double& frameDelayL, double& frameDelayR);
     
     // Total number of azimuths after interpolation.
     static const unsigned NumberOfTotalAzimuths;
 
-    void reportMemoryUsage(MemoryObjectInfo*) const;
+    static size_t fftSizeForSampleRate(float sampleRate);
 
 private:
-    HRTFElevation(PassOwnPtr<HRTFKernelList> kernelListL, int elevation, float sampleRate)
-        : m_kernelListL(kernelListL)
-        , m_elevationAngle(elevation)
+    HRTFElevation(const HRTFElevation& other) MOZ_DELETE;
+    void operator=(const HRTFElevation& other) MOZ_DELETE;
+
+    HRTFElevation(HRTFKernelList *kernelListL, int elevation, float sampleRate)
+        : m_elevationAngle(elevation)
         , m_sampleRate(sampleRate)
     {
+        m_kernelListL.SwapElements(*kernelListL);
     }
 
     // Returns the list of left ear HRTFKernels for all the azimuths going from 0 to 360 degrees.
-    HRTFKernelList* kernelListL() { return m_kernelListL.get(); }
+    const HRTFKernelList& kernelListL() { return m_kernelListL; }
 
     // Given a specific azimuth and elevation angle, returns the left HRTFKernel.
     // Values for azimuth must be multiples of 15 in 0 -> 345,
     // but not all azimuths are available for elevations > +45.
     // Valid values for elevation are -45 -> +90 in 15 degree increments.
-    // Returns true on success.
-    static bool calculateKernelForAzimuthElevation(int azimuth, int elevation, SpeexResamplerState* resampler, float sampleRate,
-                                                   RefPtr<HRTFKernel>& kernelL);
+    static nsReturnRef<HRTFKernel> calculateKernelForAzimuthElevation(int azimuth, int elevation, SpeexResamplerState* resampler, float sampleRate);
 
-    OwnPtr<HRTFKernelList> m_kernelListL;
+    HRTFKernelList m_kernelListL;
     double m_elevationAngle;
     float m_sampleRate;
 };
 
 } // namespace WebCore
 
+template <>
+class nsAutoRefTraits<WebCore::HRTFElevation> :
+    public nsPointerRefTraits<WebCore::HRTFElevation> {
+public:
+    static void Release(WebCore::HRTFElevation* ptr) { delete(ptr); }
+};
+
 #endif // HRTFElevation_h
--- a/content/media/webaudio/blink/moz.build
+++ b/content/media/webaudio/blink/moz.build
@@ -7,16 +7,17 @@
 MODULE = 'content'
 
 CPP_SOURCES += [
     'Biquad.cpp',
     'DirectConvolver.cpp',
     'DynamicsCompressor.cpp',
     'DynamicsCompressorKernel.cpp',
     'FFTConvolver.cpp',
+    'HRTFElevation.cpp',
     'HRTFKernel.cpp',
     'Reverb.cpp',
     'ReverbAccumulationBuffer.cpp',
     'ReverbConvolver.cpp',
     'ReverbConvolverStage.cpp',
     'ReverbInputBuffer.cpp',
     'ZeroPole.cpp',
 ]