// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/webaudio/stereo_panner_node.h"

#include "third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/platform/audio/stereo_panner.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"

namespace blink {

StereoPannerHandler::StereoPannerHandler(AudioNode& node,
                                         float sample_rate,
                                         AudioParamHandler& pan)
    : AudioHandler(kNodeTypeStereoPanner, node, sample_rate),
      pan_(&pan),
      sample_accurate_pan_values_(audio_utilities::kRenderQuantumFrames) {
  AddInput();
  AddOutput(2);

  // The node-specific default mixing rules declare that StereoPannerNode
  // can handle mono to stereo and stereo to stereo conversion.
  channel_count_ = 2;
  SetInternalChannelCountMode(kClampedMax);
  SetInternalChannelInterpretation(AudioBus::kSpeakers);

  Initialize();
}

scoped_refptr<StereoPannerHandler> StereoPannerHandler::Create(
    AudioNode& node,
    float sample_rate,
    AudioParamHandler& pan) {
  return base::AdoptRef(new StereoPannerHandler(node, sample_rate, pan));
}

StereoPannerHandler::~StereoPannerHandler() {
  Uninitialize();
}

void StereoPannerHandler::Process(uint32_t frames_to_process) {
  AudioBus* output_bus = Output(0).Bus();

  if (!IsInitialized() || !Input(0).IsConnected() || !stereo_panner_.get()) {
    output_bus->Zero();
    return;
  }

  scoped_refptr<AudioBus> input_bus = Input(0).Bus();
  if (!input_bus) {
    output_bus->Zero();
    return;
  }

  bool is_sample_accurate = pan_->HasSampleAccurateValues();

  if (is_sample_accurate && pan_->IsAudioRate()) {
    // Apply sample-accurate panning specified by AudioParam automation.
    DCHECK_LE(frames_to_process, sample_accurate_pan_values_.size());
    float* pan_values = sample_accurate_pan_values_.Data();
    pan_->CalculateSampleAccurateValues(pan_values, frames_to_process);
    stereo_panner_->PanWithSampleAccurateValues(input_bus.get(), output_bus,
                                                pan_values, frames_to_process);
    return;
  }

  // The pan value is not sample-accurate or not a-rate.  In this case, we have
  // a fixed pan value for the render and just need to incorporate any inputs to
  // the value, if any.
  float pan_value = is_sample_accurate ? pan_->FinalValue() : pan_->Value();

  stereo_panner_->PanToTargetValue(input_bus.get(), output_bus, pan_value,
                                   frames_to_process);
}

void StereoPannerHandler::ProcessOnlyAudioParams(uint32_t frames_to_process) {
  float values[audio_utilities::kRenderQuantumFrames];
  DCHECK_LE(frames_to_process, audio_utilities::kRenderQuantumFrames);

  pan_->CalculateSampleAccurateValues(values, frames_to_process);
}

void StereoPannerHandler::Initialize() {
  if (IsInitialized())
    return;

  stereo_panner_ = std::make_unique<StereoPanner>(Context()->sampleRate());

  AudioHandler::Initialize();
}

void StereoPannerHandler::SetChannelCount(unsigned channel_count,
                                          ExceptionState& exception_state) {
  DCHECK(IsMainThread());
  BaseAudioContext::GraphAutoLocker locker(Context());

  // A PannerNode only supports 1 or 2 channels
  if (channel_count > 0 && channel_count <= 2) {
    if (channel_count_ != channel_count) {
      channel_count_ = channel_count;
      if (InternalChannelCountMode() != kMax)
        UpdateChannelsForInputs();
    }
  } else {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kNotSupportedError,
        ExceptionMessages::IndexOutsideRange<uint32_t>(
            "channelCount", channel_count, 1,
            ExceptionMessages::kInclusiveBound, 2,
            ExceptionMessages::kInclusiveBound));
  }
}

void StereoPannerHandler::SetChannelCountMode(const String& mode,
                                              ExceptionState& exception_state) {
  DCHECK(IsMainThread());
  BaseAudioContext::GraphAutoLocker locker(Context());

  ChannelCountMode old_mode = InternalChannelCountMode();

  if (mode == "clamped-max") {
    new_channel_count_mode_ = kClampedMax;
  } else if (mode == "explicit") {
    new_channel_count_mode_ = kExplicit;
  } else if (mode == "max") {
    // This is not supported for a StereoPannerNode, which can only handle
    // 1 or 2 channels.
    exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
                                      "StereoPanner: 'max' is not allowed");
    new_channel_count_mode_ = old_mode;
  } else {
    // Do nothing for other invalid values.
    new_channel_count_mode_ = old_mode;
  }

  if (new_channel_count_mode_ != old_mode)
    Context()->GetDeferredTaskHandler().AddChangedChannelCountMode(this);
}

// ----------------------------------------------------------------

StereoPannerNode::StereoPannerNode(BaseAudioContext& context)
    : AudioNode(context),
      pan_(AudioParam::Create(context,
                              Uuid(),
                              AudioParamHandler::kParamTypeStereoPannerPan,
                              0,
                              AudioParamHandler::AutomationRate::kAudio,
                              AudioParamHandler::AutomationRateMode::kVariable,
                              -1,
                              1)) {
  SetHandler(StereoPannerHandler::Create(*this, context.sampleRate(),
                                         pan_->Handler()));
}

StereoPannerNode* StereoPannerNode::Create(BaseAudioContext& context,
                                           ExceptionState& exception_state) {
  DCHECK(IsMainThread());

  return MakeGarbageCollected<StereoPannerNode>(context);
}

StereoPannerNode* StereoPannerNode::Create(BaseAudioContext* context,
                                           const StereoPannerOptions* options,
                                           ExceptionState& exception_state) {
  StereoPannerNode* node = Create(*context, exception_state);

  if (!node)
    return nullptr;

  node->HandleChannelOptions(options, exception_state);

  node->pan()->setValue(options->pan());

  return node;
}

void StereoPannerNode::Trace(Visitor* visitor) const {
  visitor->Trace(pan_);
  AudioNode::Trace(visitor);
}

AudioParam* StereoPannerNode::pan() const {
  return pan_;
}

void StereoPannerNode::ReportDidCreate() {
  GraphTracer().DidCreateAudioNode(this);
  GraphTracer().DidCreateAudioParam(pan_);
}

void StereoPannerNode::ReportWillBeDestroyed() {
  GraphTracer().WillDestroyAudioParam(pan_);
  GraphTracer().WillDestroyAudioNode(this);
}

}  // namespace blink
