b=815643 Add Blink's HRTFElevation to the build r=ehsan
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 08 Aug 2013 21:38:30 +1200
changeset 142361 395fc5b9593c
parent 142360 5a05c2215091
child 142362 316df2d96b24
push id32374
push userktomlinson@mozilla.com
push dateTue, 13 Aug 2013 02:49:14 +0000
treeherdermozilla-inbound@62ad090a94a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs815643
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=815643 Add Blink's HRTFElevation to the build r=ehsan
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',
 ]