blob: 1a182300e421d00a03957d7a8a801dfc0e8e6d8b [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_PANNER_HANDLER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_PANNER_HANDLER_H_
#include <memory>
#include "base/synchronization/lock.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_distance_model_type.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_panning_model_type.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
#include "third_party/blink/renderer/platform/audio/cone_effect.h"
#include "third_party/blink/renderer/platform/audio/distance_effect.h"
#include "third_party/blink/renderer/platform/audio/panner.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/vector3d_f.h"
namespace blink {
class AudioBus;
class AudioListenerHandler;
class AudioParamHandler;
class PannerHandler final : public AudioHandler {
public:
// These enums are used to distinguish what cached values of panner are dirty.
enum {
kAzimuthElevationDirty = 0x1,
kDistanceConeGainDirty = 0x2,
};
static scoped_refptr<PannerHandler> Create(AudioNode&,
float sample_rate,
AudioParamHandler& position_x,
AudioParamHandler& position_y,
AudioParamHandler& position_z,
AudioParamHandler& orientation_x,
AudioParamHandler& orientation_y,
AudioParamHandler& orientation_z);
PannerHandler(const PannerHandler&) = delete;
PannerHandler& operator=(const PannerHandler&) = delete;
~PannerHandler() override;
// AudioHandler
void Initialize() override;
double LatencyTime() const override {
return panner_ ? panner_->LatencyTime() : 0;
}
void Process(uint32_t frames_to_process) override;
void ProcessIfNecessary(uint32_t frames_to_process) override;
void ProcessOnlyAudioParams(uint32_t frames_to_process) override;
void ProcessSampleAccurateValues(AudioBus* destination,
const AudioBus* source,
uint32_t frames_to_process);
bool RequiresTailProcessing() const override;
void SetChannelCount(unsigned, ExceptionState&) override;
void SetChannelCountMode(V8ChannelCountMode::Enum, ExceptionState&) override;
double TailTime() const override { return panner_ ? panner_->TailTime() : 0; }
void Uninitialize() override;
double ConeInnerAngle() const { return cone_effect_.InnerAngle(); }
double ConeOuterAngle() const { return cone_effect_.OuterAngle(); }
double ConeOuterGain() const { return cone_effect_.OuterGain(); }
V8DistanceModelType::Enum DistanceModel() const;
double MaxDistance() { return distance_effect_.MaxDistance(); }
V8PanningModelType::Enum PanningModel() const;
double RefDistance() { return distance_effect_.RefDistance(); }
double RolloffFactor() { return distance_effect_.RolloffFactor(); }
void SetConeInnerAngle(double angles_in_degrees);
void SetConeOuterAngle(double angles_in_degrees);
void SetConeOuterGain(double);
void SetDistanceModel(V8DistanceModelType::Enum);
void SetMaxDistance(double);
void SetOrientation(float x, float y, float z, ExceptionState&);
void SetPanningModel(V8PanningModelType::Enum);
void SetPosition(float x, float y, float z, ExceptionState&);
void SetRefDistance(double);
void SetRolloffFactor(double);
void MarkPannerAsDirty(unsigned);
private:
PannerHandler(AudioNode&,
float sample_rate,
AudioParamHandler& position_x,
AudioParamHandler& position_y,
AudioParamHandler& position_z,
AudioParamHandler& orientation_x,
AudioParamHandler& orientation_y,
AudioParamHandler& orientation_z);
// Returns true on successful operation.
bool SetPanningModel(Panner::PanningModel);
bool SetDistanceModel(unsigned);
gfx::Point3F GetPosition() const;
gfx::Vector3dF Orientation() const;
// Returns a combined gain attenuation for azimuth and elevation.
void CalculateAzimuthElevation(double* out_azimuth,
double* out_elevation,
const gfx::Point3F& position,
const gfx::Point3F& listener_position,
const gfx::Vector3dF& listener_forward,
const gfx::Vector3dF& listener_up);
// Returns a combined gain attenuation for distance and sound cone.
float CalculateDistanceConeGain(const gfx::Point3F& position,
const gfx::Vector3dF& orientation,
const gfx::Point3F& listener_position);
// The in-place version of `CalculateAzimuthElevation` above for k-rate.
void AzimuthElevation(double* out_azimuth, double* out_elevation);
// Returns a combined gain attenuation for distance and sound cone in k-rate.
float DistanceConeGain();
bool IsAzimuthElevationDirty() const { return is_azimuth_elevation_dirty_; }
bool IsDistanceConeGainDirty() const { return is_distance_cone_gain_dirty_; }
void UpdateDirtyState();
// True if any of this panner's AudioParams have automations.
bool HasSampleAccurateValues() const;
// True if any of the panner's AudioParams are set for a-rate automations
// (the default).
bool IsAudioRate() const;
std::unique_ptr<Panner> panner_;
Panner::PanningModel panning_model_;
unsigned distance_model_ = DistanceEffect::kModelInverse;
gfx::Point3F last_position_;
gfx::Vector3dF last_orientation_;
double cached_azimuth_ = 0;
double cached_elevation_ = 0;
bool is_azimuth_elevation_dirty_ = true;
DistanceEffect distance_effect_;
ConeEffect cone_effect_;
float cached_distance_cone_gain_ = 1.0f;
bool is_distance_cone_gain_dirty_ = true;
scoped_refptr<AudioParamHandler> position_x_;
scoped_refptr<AudioParamHandler> position_y_;
scoped_refptr<AudioParamHandler> position_z_;
scoped_refptr<AudioParamHandler> orientation_x_;
scoped_refptr<AudioParamHandler> orientation_y_;
scoped_refptr<AudioParamHandler> orientation_z_;
scoped_refptr<AudioListenerHandler> listener_handler_;
// Sample-accurate value arrays for PannerHandler.
AudioFloatArray panner_x_values_;
AudioFloatArray panner_y_values_;
AudioFloatArray panner_z_values_;
AudioFloatArray orientation_x_values_;
AudioFloatArray orientation_y_values_;
AudioFloatArray orientation_z_values_;
AudioDoubleArray azimuth_values_;
AudioDoubleArray elevation_values_;
AudioFloatArray total_gain_values_;
// To synchronize `Process()` with the setting of this panner's state. (e.g.
// position, orientation, distance, sound cone, and the listener)
mutable base::Lock process_lock_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_PANNER_HANDLER_H_