/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "audio/utility/channel_mixer.h"

#include "audio/utility/channel_mixing_matrix.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"

namespace webrtc {

ChannelMixer::ChannelMixer(ChannelLayout input_layout,
                           size_t input_channels,
                           ChannelLayout output_layout,
                           size_t output_channels)
    : input_layout_(input_layout),
      output_layout_(output_layout),
      input_channels_(input_channels),
      output_channels_(output_channels) {
  // Create the transformation matrix.
  ChannelMixingMatrix matrix_builder(input_layout_, input_channels_,
                                     output_layout_, output_channels_);
  remapping_ = matrix_builder.CreateTransformationMatrix(&matrix_);
}

ChannelMixer::ChannelMixer(ChannelLayout input_layout,
                           ChannelLayout output_layout)
    : ChannelMixer(input_layout,
                   ChannelLayoutToChannelCount(input_layout),
                   output_layout,
                   ChannelLayoutToChannelCount(output_layout)) {}

ChannelMixer::~ChannelMixer() = default;

void ChannelMixer::Transform(AudioFrame* frame) {
  RTC_DCHECK(frame);
  RTC_DCHECK_EQ(matrix_[0].size(), static_cast<size_t>(input_channels_));
  RTC_DCHECK_EQ(matrix_.size(), static_cast<size_t>(output_channels_));

  // Leave the audio frame intact if the channel layouts for in and out are
  // identical.
  if (input_layout_ == output_layout_) {
    return;
  }

  if (IsUpMixing()) {
    RTC_CHECK_LE(frame->samples_per_channel() * output_channels_,
                 frame->max_16bit_samples());
  }

  // Only change the number of output channels if the audio frame is muted.
  if (frame->muted()) {
    frame->SetLayoutAndNumChannels(output_layout_, output_channels_);
    return;
  }

  const int16_t* in_audio = frame->data();

  // Only allocate fresh memory at first access or if the required size has
  // increased.
  // TODO(henrika): we might be able to do downmixing in-place and thereby avoid
  // extra memory allocation and a memcpy.
  const size_t num_elements = frame->samples_per_channel() * output_channels_;
  if (audio_vector_ == nullptr || num_elements > audio_vector_size_) {
    audio_vector_.reset(new int16_t[num_elements]);
    audio_vector_size_ = num_elements;
  }
  int16_t* out_audio = audio_vector_.get();

  // Modify the number of channels by creating a weighted sum of input samples
  // where the weights (scale factors) for each output sample are given by the
  // transformation matrix.
  for (size_t i = 0; i < frame->samples_per_channel(); i++) {
    for (size_t output_ch = 0; output_ch < output_channels_; ++output_ch) {
      float acc_value = 0.0f;
      for (size_t input_ch = 0; input_ch < input_channels_; ++input_ch) {
        const float scale = matrix_[output_ch][input_ch];
        // Scale should always be positive.
        RTC_DCHECK_GE(scale, 0);
        // Each output sample is a weighted sum of input samples.
        acc_value += scale * in_audio[i * input_channels_ + input_ch];
      }
      const size_t index = output_channels_ * i + output_ch;
      RTC_CHECK_LE(index, audio_vector_size_);
      out_audio[index] = rtc::saturated_cast<int16_t>(acc_value);
    }
  }

  // Update channel information.
  frame->SetLayoutAndNumChannels(output_layout_, output_channels_);

  // Copy the output result to the audio frame in `frame`.
  memcpy(
      frame->mutable_data(), out_audio,
      sizeof(int16_t) * frame->samples_per_channel() * frame->num_channels());
}

}  // namespace webrtc
