Commit d8bfaa0c authored by rtoy's avatar rtoy Committed by Commit bot

HRTF panner should handle the case of no loaded HRTF database

Currently, the panner node checks to see if the HRTF database is
loaded and does the copy of the input if necessary.  This is the wrong
abstraction; the HRTF panner should copy the input if the database is
not ready.

In this way, the panner doesn't need to know about this implementation
detail, and we also get the correct distance and cone gains applied.

BUG=629858
TEST=

Review-Url: https://codereview.chromium.org/2170973002
Cr-Commit-Position: refs/heads/master@{#406988}
parent b83e4b63
...@@ -131,16 +131,10 @@ void PannerHandler::process(size_t framesToProcess) ...@@ -131,16 +131,10 @@ void PannerHandler::process(size_t framesToProcess)
MutexTryLocker tryListenerLocker(listener()->listenerLock()); MutexTryLocker tryListenerLocker(listener()->listenerLock());
if (tryLocker.locked() && tryListenerLocker.locked()) { if (tryLocker.locked() && tryListenerLocker.locked()) {
// HRTFDatabase should be loaded before proceeding when the panning model is HRTF. if (!context()->hasRealtimeConstraint() && m_panningModel == Panner::PanningModelHRTF) {
if (m_panningModel == Panner::PanningModelHRTF && !listener()->isHRTFDatabaseLoaded()) { // For an OfflineAudioContext, we need to make sure the HRTFDatabase
if (context()->hasRealtimeConstraint()) { // is loaded before proceeding. For realtime contexts, we don't
// Realtime AudioContext's cannot block on the HRTFDatabase // have to wait. The HRTF panner handles that case itself.
// loader. Instead, copy the input to the output so we can at
// least hear something until the database is ready.
destination->copyFrom(*source, m_channelInterpretation);
return;
}
listener()->waitForHRTFDatabaseLoaderThreadCompletion(); listener()->waitForHRTFDatabaseLoaderThreadCompletion();
} }
...@@ -161,7 +155,7 @@ void PannerHandler::process(size_t framesToProcess) ...@@ -161,7 +155,7 @@ void PannerHandler::process(size_t framesToProcess)
azimuthElevation(&azimuth, &elevation); azimuthElevation(&azimuth, &elevation);
m_panner->pan(azimuth, elevation, source, destination, framesToProcess); m_panner->pan(azimuth, elevation, source, destination, framesToProcess, internalChannelInterpretation());
// Get the distance and cone gain. // Get the distance and cone gain.
float totalGain = distanceConeGain(); float totalGain = distanceConeGain();
...@@ -231,7 +225,7 @@ void PannerHandler::processSampleAccurateValues(AudioBus* destination, const Aud ...@@ -231,7 +225,7 @@ void PannerHandler::processSampleAccurateValues(AudioBus* destination, const Aud
totalGain[k] = calculateDistanceConeGain(pannerPosition, orientation, listenerPosition); totalGain[k] = calculateDistanceConeGain(pannerPosition, orientation, listenerPosition);
} }
m_panner->panWithSampleAccurateValues(azimuth, elevation, source, destination, framesToProcess); m_panner->panWithSampleAccurateValues(azimuth, elevation, source, destination, framesToProcess, internalChannelInterpretation());
destination->copyWithSampleAccurateGainValuesFrom(*destination, totalGain, framesToProcess); destination->copyWithSampleAccurateGainValuesFrom(*destination, totalGain, framesToProcess);
} }
......
...@@ -36,7 +36,7 @@ EqualPowerPanner::EqualPowerPanner(float sampleRate) ...@@ -36,7 +36,7 @@ EqualPowerPanner::EqualPowerPanner(float sampleRate)
{ {
} }
void EqualPowerPanner::pan(double azimuth, double /*elevation*/, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) void EqualPowerPanner::pan(double azimuth, double /*elevation*/, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation)
{ {
bool isInputSafe = inputBus && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2) && framesToProcess <= inputBus->length(); bool isInputSafe = inputBus && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2) && framesToProcess <= inputBus->length();
ASSERT(isInputSafe); ASSERT(isInputSafe);
...@@ -153,7 +153,7 @@ void EqualPowerPanner::calculateDesiredGain(double& desiredGainL, double& desire ...@@ -153,7 +153,7 @@ void EqualPowerPanner::calculateDesiredGain(double& desiredGainL, double& desire
desiredGainR = std::sin(piOverTwoDouble * desiredPanPosition); desiredGainR = std::sin(piOverTwoDouble * desiredPanPosition);
} }
void EqualPowerPanner::panWithSampleAccurateValues(double* azimuth, double* /*elevation*/, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) void EqualPowerPanner::panWithSampleAccurateValues(double* azimuth, double* /*elevation*/, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation)
{ {
bool isInputSafe = inputBus && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2) && framesToProcess <= inputBus->length(); bool isInputSafe = inputBus && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2) && framesToProcess <= inputBus->length();
DCHECK(isInputSafe); DCHECK(isInputSafe);
......
...@@ -35,8 +35,8 @@ class PLATFORM_EXPORT EqualPowerPanner final : public Panner { ...@@ -35,8 +35,8 @@ class PLATFORM_EXPORT EqualPowerPanner final : public Panner {
public: public:
EqualPowerPanner(float sampleRate); EqualPowerPanner(float sampleRate);
void pan(double azimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBuf, size_t framesToProcess) override; void pan(double azimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBuf, size_t framesToProcess, AudioBus::ChannelInterpretation) override;
void panWithSampleAccurateValues(double* azimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) override; void panWithSampleAccurateValues(double* azimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation) override;
void reset() override { } void reset() override { }
......
...@@ -117,7 +117,7 @@ int HRTFPanner::calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azi ...@@ -117,7 +117,7 @@ int HRTFPanner::calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azi
return desiredAzimuthIndex; return desiredAzimuthIndex;
} }
void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation channelInterpretation)
{ {
unsigned numInputChannels = inputBus ? inputBus->numberOfChannels() : 0; unsigned numInputChannels = inputBus ? inputBus->numberOfChannels() : 0;
...@@ -134,9 +134,8 @@ void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* in ...@@ -134,9 +134,8 @@ void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* in
} }
HRTFDatabase* database = m_databaseLoader->database(); HRTFDatabase* database = m_databaseLoader->database();
ASSERT(database);
if (!database) { if (!database) {
outputBus->zero(); outputBus->copyFrom(*inputBus, channelInterpretation);
return; return;
} }
...@@ -292,7 +291,7 @@ void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* in ...@@ -292,7 +291,7 @@ void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBus* in
} }
} }
void HRTFPanner::panWithSampleAccurateValues(double* desiredAzimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) void HRTFPanner::panWithSampleAccurateValues(double* desiredAzimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation channelInterpretation)
{ {
// Sample-accurate (a-rate) HRTF panner is not implemented, just k-rate. Just grab the current // Sample-accurate (a-rate) HRTF panner is not implemented, just k-rate. Just grab the current
// azimuth/elevation and use that. // azimuth/elevation and use that.
...@@ -302,7 +301,7 @@ void HRTFPanner::panWithSampleAccurateValues(double* desiredAzimuth, double* ele ...@@ -302,7 +301,7 @@ void HRTFPanner::panWithSampleAccurateValues(double* desiredAzimuth, double* ele
// one output sample for each possibly different impulse response. That N^2. Previously, we // one output sample for each possibly different impulse response. That N^2. Previously, we
// used an FFT to do them all at once for a complexity of N/log2(N). Hence, N/log2(N) times // used an FFT to do them all at once for a complexity of N/log2(N). Hence, N/log2(N) times
// more complex.) // more complex.)
pan(desiredAzimuth[0], elevation[0], inputBus, outputBus, framesToProcess); pan(desiredAzimuth[0], elevation[0], inputBus, outputBus, framesToProcess, channelInterpretation);
} }
double HRTFPanner::tailTime() const double HRTFPanner::tailTime() const
......
...@@ -38,8 +38,8 @@ public: ...@@ -38,8 +38,8 @@ public:
~HRTFPanner() override; ~HRTFPanner() override;
// Panner // Panner
void pan(double azimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) override; void pan(double azimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation) override;
void panWithSampleAccurateValues(double* azimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) override; void panWithSampleAccurateValues(double* azimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation) override;
void reset() override; void reset() override;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define Panner_h #define Panner_h
#include "platform/PlatformExport.h" #include "platform/PlatformExport.h"
#include "platform/audio/AudioBus.h"
#include "wtf/Allocator.h" #include "wtf/Allocator.h"
#include "wtf/Noncopyable.h" #include "wtf/Noncopyable.h"
#include "wtf/build_config.h" #include "wtf/build_config.h"
...@@ -37,7 +38,6 @@ ...@@ -37,7 +38,6 @@
namespace blink { namespace blink {
class AudioBus;
class HRTFDatabaseLoader; class HRTFDatabaseLoader;
// Abstract base class for panning a mono or stereo source. // Abstract base class for panning a mono or stereo source.
...@@ -58,8 +58,8 @@ public: ...@@ -58,8 +58,8 @@ public:
virtual ~Panner() { }; virtual ~Panner() { };
virtual void pan(double azimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) = 0; virtual void pan(double azimuth, double elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation) = 0;
virtual void panWithSampleAccurateValues(double* azimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) = 0; virtual void panWithSampleAccurateValues(double* azimuth, double* elevation, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess, AudioBus::ChannelInterpretation) = 0;
virtual void reset() = 0; virtual void reset() = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment