From 715c2a763f56e8b7a0ffe993e0be443e9e120b7f Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 8 Aug 2013 21:38:29 +1200 Subject: [PATCH] b=815643 Use symmetry to halve the number of HRTF kernels calculated and cached r=ehsan --HG-- extra : rebase_source : 12e4a114630e793c22d3e335c38c641a6bc20ee2 --- .../media/webaudio/blink/HRTFElevation.cpp | 36 ++++++++----------- content/media/webaudio/blink/HRTFElevation.h | 25 ++++++------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/content/media/webaudio/blink/HRTFElevation.cpp b/content/media/webaudio/blink/HRTFElevation.cpp index 3f51ee8cd79..635f09b3441 100644 --- a/content/media/webaudio/blink/HRTFElevation.cpp +++ b/content/media/webaudio/blink/HRTFElevation.cpp @@ -52,8 +52,8 @@ const unsigned HRTFElevation::NumberOfTotalAzimuths = NumberOfRawAzimuths * Inte // Number of frames in an individual impulse response. const size_t ResponseFrameSize = 256; -bool HRTFElevation::calculateKernelsForAzimuthElevation(int azimuth, int elevation, float sampleRate, const String& subjectName, - RefPtr& kernelL, RefPtr& kernelR) +bool HRTFElevation::calculateKernelForAzimuthElevation(int azimuth, int elevation, float sampleRate, const String& subjectName, + RefPtr& kernelL) { // Valid values for azimuth are 0 -> 345 in 15 degree increments. // Valid values for elevation are -45 -> +90 in 15 degree increments. @@ -92,7 +92,6 @@ bool HRTFElevation::calculateKernelsForAzimuthElevation(int azimuth, int elevati return false; AudioChannel* leftEarImpulseResponse = impulseResponse->channelByType(AudioBus::ChannelLeft); - AudioChannel* rightEarImpulseResponse = impulseResponse->channelByType(AudioBus::ChannelRight); // Note that depending on the fftSize returned by the panner, we may be truncating the impulse response we just loaded in. const size_t fftSize = HRTFPanner::fftSizeForSampleRate(sampleRate); @@ -101,7 +100,6 @@ bool HRTFElevation::calculateKernelsForAzimuthElevation(int azimuth, int elevati return false; kernelL = HRTFKernel::create(leftEarImpulseResponse, fftSize / 2, sampleRate); - kernelR = HRTFKernel::create(rightEarImpulseResponse, fftSize / 2, sampleRate); return true; } @@ -146,7 +144,6 @@ PassOwnPtr HRTFElevation::createForSubject(const String& subjectN return nullptr; OwnPtr kernelListL = adoptPtr(new HRTFKernelList(NumberOfTotalAzimuths)); - OwnPtr kernelListR = adoptPtr(new HRTFKernelList(NumberOfTotalAzimuths)); // Load convolution kernels from HRTF files. int interpolatedIndex = 0; @@ -155,7 +152,7 @@ PassOwnPtr HRTFElevation::createForSubject(const String& subjectN int maxElevation = maxElevations[rawIndex]; int actualElevation = min(elevation, maxElevation); - bool success = calculateKernelsForAzimuthElevation(rawIndex * AzimuthSpacing, actualElevation, sampleRate, subjectName, kernelListL->at(interpolatedIndex), kernelListR->at(interpolatedIndex)); + bool success = calculateKernelForAzimuthElevation(rawIndex * AzimuthSpacing, actualElevation, sampleRate, subjectName, kernelListL->at(interpolatedIndex)); if (!success) return nullptr; @@ -171,11 +168,10 @@ PassOwnPtr HRTFElevation::createForSubject(const String& subjectN float x = float(jj) / float(InterpolationFactor); // interpolate from 0 -> 1 (*kernelListL)[i + jj] = HRTFKernel::createInterpolatedKernel(kernelListL->at(i).get(), kernelListL->at(j).get(), x); - (*kernelListR)[i + jj] = HRTFKernel::createInterpolatedKernel(kernelListR->at(i).get(), kernelListR->at(j).get(), x); } } - OwnPtr hrtfElevation = adoptPtr(new HRTFElevation(kernelListL.release(), kernelListR.release(), elevation, sampleRate)); + OwnPtr hrtfElevation = adoptPtr(new HRTFElevation(kernelListL.release(), elevation, sampleRate)); return hrtfElevation.release(); } @@ -188,23 +184,19 @@ PassOwnPtr HRTFElevation::createByInterpolatingSlices(HRTFElevati ASSERT(x >= 0.0 && x < 1.0); OwnPtr kernelListL = adoptPtr(new HRTFKernelList(NumberOfTotalAzimuths)); - OwnPtr kernelListR = adoptPtr(new HRTFKernelList(NumberOfTotalAzimuths)); HRTFKernelList* kernelListL1 = hrtfElevation1->kernelListL(); - HRTFKernelList* kernelListR1 = hrtfElevation1->kernelListR(); HRTFKernelList* kernelListL2 = hrtfElevation2->kernelListL(); - HRTFKernelList* kernelListR2 = hrtfElevation2->kernelListR(); // 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); - (*kernelListR)[i] = HRTFKernel::createInterpolatedKernel(kernelListR1->at(i).get(), kernelListR2->at(i).get(), x); } // Interpolate elevation angle. double angle = (1.0 - x) * hrtfElevation1->elevationAngle() + x * hrtfElevation2->elevationAngle(); - OwnPtr hrtfElevation = adoptPtr(new HRTFElevation(kernelListL.release(), kernelListR.release(), static_cast(angle), sampleRate)); + OwnPtr hrtfElevation = adoptPtr(new HRTFElevation(kernelListL.release(), static_cast(angle), sampleRate)); return hrtfElevation.release(); } @@ -225,16 +217,19 @@ void HRTFElevation::getKernelsFromAzimuth(double azimuthBlend, unsigned azimuthI return; } - // Return the left and right kernels. + // Return the left and right kernels, + // using symmetry to produce the right kernel. kernelL = m_kernelListL->at(azimuthIndex).get(); - kernelR = m_kernelListR->at(azimuthIndex).get(); + int azimuthIndexR = (numKernels - azimuthIndex) % numKernels; + kernelR = m_kernelListL->at(azimuthIndexR).get(); - frameDelayL = m_kernelListL->at(azimuthIndex)->frameDelay(); - frameDelayR = m_kernelListR->at(azimuthIndex)->frameDelay(); + frameDelayL = kernelL->frameDelay(); + frameDelayR = kernelR->frameDelay(); - int azimuthIndex2 = (azimuthIndex + 1) % numKernels; - double frameDelay2L = m_kernelListL->at(azimuthIndex2)->frameDelay(); - double frameDelay2R = m_kernelListR->at(azimuthIndex2)->frameDelay(); + int azimuthIndex2L = (azimuthIndex + 1) % numKernels; + double frameDelay2L = m_kernelListL->at(azimuthIndex2L)->frameDelay(); + int azimuthIndex2R = (numKernels - azimuthIndex2L) % numKernels; + double frameDelay2R = m_kernelListL->at(azimuthIndex2R)->frameDelay(); // Linearly interpolate delays. frameDelayL = (1.0 - azimuthBlend) * frameDelayL + azimuthBlend * frameDelay2L; @@ -245,7 +240,6 @@ void HRTFElevation::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::AudioSharedData); info.addMember(m_kernelListL, "kernelListL"); - info.addMember(m_kernelListR, "kernelListR"); } } // namespace WebCore diff --git a/content/media/webaudio/blink/HRTFElevation.h b/content/media/webaudio/blink/HRTFElevation.h index 8596248e87d..370fcc94a41 100644 --- a/content/media/webaudio/blink/HRTFElevation.h +++ b/content/media/webaudio/blink/HRTFElevation.h @@ -55,10 +55,6 @@ public: // Given two HRTFElevations, and an interpolation factor x: 0 -> 1, returns an interpolated HRTFElevation. static PassOwnPtr createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate); - // Returns the list of left or right ear HRTFKernels for all the azimuths going from 0 to 360 degrees. - HRTFKernelList* kernelListL() { return m_kernelListL.get(); } - HRTFKernelList* kernelListR() { return m_kernelListR.get(); } - double elevationAngle() const { return m_elevationAngle; } unsigned numberOfAzimuths() const { return NumberOfTotalAzimuths; } float sampleRate() const { return m_sampleRate; } @@ -79,26 +75,27 @@ public: // Total number of azimuths after interpolation. static const unsigned NumberOfTotalAzimuths; - // Given a specific azimuth and elevation angle, returns the left and right HRTFKernel. - // Valid values for azimuth are 0 -> 345 in 15 degree increments. - // Valid values for elevation are -45 -> +90 in 15 degree increments. - // Returns true on success. - static bool calculateKernelsForAzimuthElevation(int azimuth, int elevation, float sampleRate, const String& subjectName, - RefPtr& kernelL, RefPtr& kernelR); - void reportMemoryUsage(MemoryObjectInfo*) const; private: - HRTFElevation(PassOwnPtr kernelListL, PassOwnPtr kernelListR, int elevation, float sampleRate) + HRTFElevation(PassOwnPtr kernelListL, int elevation, float sampleRate) : m_kernelListL(kernelListL) - , m_kernelListR(kernelListR) , m_elevationAngle(elevation) , m_sampleRate(sampleRate) { } + // Returns the list of left ear HRTFKernels for all the azimuths going from 0 to 360 degrees. + HRTFKernelList* kernelListL() { return m_kernelListL.get(); } + + // Given a specific azimuth and elevation angle, returns the left HRTFKernel. + // Valid values for azimuth are 0 -> 345 in 15 degree increments. + // Valid values for elevation are -45 -> +90 in 15 degree increments. + // Returns true on success. + static bool calculateKernelForAzimuthElevation(int azimuth, int elevation, float sampleRate, const String& subjectName, + RefPtr& kernelL); + OwnPtr m_kernelListL; - OwnPtr m_kernelListR; double m_elevationAngle; float m_sampleRate; };