/*
 *  Copyright (c) 2017 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 "modules/audio_mixer/frame_combiner.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <span>
#include <utility>
#include <vector>

#include "api/audio/audio_frame.h"
#include "api/audio/audio_view.h"
#include "api/rtp_packet_info.h"
#include "api/rtp_packet_infos.h"
#include "common_audio/include/audio_util.h"
#include "modules/audio_mixer/audio_frame_manipulator.h"
#include "modules/audio_processing/agc2/limiter.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace {

void SetAudioFrameFields(std::span<const AudioFrame* const> mix_list,
                         size_t number_of_channels,
                         int sample_rate,
                         size_t /* number_of_streams */,
                         AudioFrame* audio_frame_for_mixing) {
  const size_t samples_per_channel =
      SampleRateToDefaultChannelSize(sample_rate);

  // TODO(minyue): Issue bugs.webrtc.org/3390.
  // Audio frame timestamp. The 'timestamp_' field is set to dummy
  // value '0', because it is only supported in the one channel case and
  // is then updated in the helper functions.
  audio_frame_for_mixing->UpdateFrame(
      0, nullptr, samples_per_channel, sample_rate, AudioFrame::kUndefined,
      AudioFrame::kVadUnknown, number_of_channels);

  if (mix_list.empty()) {
    audio_frame_for_mixing->elapsed_time_ms_ = -1;
  } else {
    audio_frame_for_mixing->timestamp_ = mix_list[0]->timestamp_;
    audio_frame_for_mixing->elapsed_time_ms_ = mix_list[0]->elapsed_time_ms_;
    audio_frame_for_mixing->ntp_time_ms_ = mix_list[0]->ntp_time_ms_;
    std::vector<RtpPacketInfo> packet_infos;
    for (const auto& frame : mix_list) {
      audio_frame_for_mixing->timestamp_ =
          std::min(audio_frame_for_mixing->timestamp_, frame->timestamp_);
      audio_frame_for_mixing->ntp_time_ms_ =
          std::min(audio_frame_for_mixing->ntp_time_ms_, frame->ntp_time_ms_);
      audio_frame_for_mixing->elapsed_time_ms_ = std::max(
          audio_frame_for_mixing->elapsed_time_ms_, frame->elapsed_time_ms_);
      packet_infos.insert(packet_infos.end(), frame->packet_infos_.begin(),
                          frame->packet_infos_.end());
    }
    audio_frame_for_mixing->packet_infos_ =
        RtpPacketInfos(std::move(packet_infos));
  }
}

void MixFewFramesWithNoLimiter(std::span<const AudioFrame* const> mix_list,
                               AudioFrame* audio_frame_for_mixing) {
  if (mix_list.empty()) {
    audio_frame_for_mixing->Mute();
    return;
  }
  RTC_DCHECK_LE(mix_list.size(), 1);
  InterleavedView<int16_t> dst = audio_frame_for_mixing->mutable_data(
      mix_list[0]->samples_per_channel_, mix_list[0]->num_channels_);
  CopySamples(dst, mix_list[0]->data_view());
}

void MixToFloatFrame(std::span<const AudioFrame* const> mix_list,
                     DeinterleavedView<float>& mixing_buffer) {
  const size_t number_of_channels = NumChannels(mixing_buffer);
  // Clear the mixing buffer.
  mixing_buffer.Clear();

  // Convert to FloatS16 and mix.
  for (size_t i = 0; i < mix_list.size(); ++i) {
    InterleavedView<const int16_t> frame_data = mix_list[i]->data_view();
    RTC_CHECK(!frame_data.empty());
    for (size_t j = 0; j < number_of_channels; ++j) {
      MonoView<float> channel = mixing_buffer[j];
      for (size_t k = 0; k < SamplesPerChannel(channel); ++k) {
        channel[k] += frame_data[number_of_channels * k + j];
      }
    }
  }
}

void RunLimiter(DeinterleavedView<float> deinterleaved, Limiter* limiter) {
  limiter->SetSamplesPerChannel(deinterleaved.samples_per_channel());
  limiter->Process(deinterleaved);
}

// Both interleaves and rounds.
void InterleaveToAudioFrame(DeinterleavedView<float> deinterleaved,
                            AudioFrame* audio_frame_for_mixing) {
  InterleavedView<int16_t> mixing_data = audio_frame_for_mixing->mutable_data(
      deinterleaved.samples_per_channel(), deinterleaved.num_channels());
  // Put data in the result frame.
  for (size_t i = 0; i < mixing_data.num_channels(); ++i) {
    auto channel = deinterleaved[i];
    for (size_t j = 0; j < mixing_data.samples_per_channel(); ++j) {
      mixing_data[mixing_data.num_channels() * j + i] =
          FloatS16ToS16(channel[j]);
    }
  }
}
}  // namespace

FrameCombiner::FrameCombiner(bool use_limiter)
    : data_dumper_(new ApmDataDumper(0)),
      limiter_(data_dumper_.get(), kMaximumChannelSize, "AudioMixer"),
      use_limiter_(use_limiter) {
  static_assert(kMaximumChannelSize * kMaximumNumberOfChannels <=
                    AudioFrame::kMaxDataSizeSamples,
                "");
}

FrameCombiner::~FrameCombiner() = default;

void FrameCombiner::Combine(std::span<AudioFrame* const> mix_list,
                            size_t number_of_channels,
                            int sample_rate,
                            size_t number_of_streams,
                            AudioFrame* audio_frame_for_mixing) {
  RTC_DCHECK(audio_frame_for_mixing);
  RTC_DCHECK_GT(sample_rate, 0);

  // Note: `mix_list` is allowed to be empty.
  // See FrameCombiner.CombiningZeroFramesShouldProduceSilence.

  // Make sure to cap `number_of_channels` to the kMaximumNumberOfChannels
  // limits since processing from hereon out will be bound by them.
  number_of_channels = std::min(number_of_channels, kMaximumNumberOfChannels);

  SetAudioFrameFields(mix_list, number_of_channels, sample_rate,
                      number_of_streams, audio_frame_for_mixing);

  size_t samples_per_channel = SampleRateToDefaultChannelSize(sample_rate);

#if RTC_DCHECK_IS_ON
  for (const auto* frame : mix_list) {
    RTC_DCHECK_EQ(samples_per_channel, frame->samples_per_channel_);
    RTC_DCHECK_EQ(sample_rate, frame->sample_rate_hz_);
  }
#endif

  // The 'num_channels_' field of frames in 'mix_list' could be
  // different from 'number_of_channels'.
  for (auto* frame : mix_list) {
    RemixFrame(number_of_channels, frame);
  }

  if (number_of_streams <= 1) {
    MixFewFramesWithNoLimiter(mix_list, audio_frame_for_mixing);
    return;
  }

  // Make sure that the size of the view based on the desired
  // `samples_per_channel` and `number_of_channels` doesn't exceed the size of
  // the `mixing_buffer_` buffer.
  RTC_DCHECK_LE(samples_per_channel, kMaximumChannelSize);
  // Since the above check is a DCHECK only, clamp down on `samples_per_channel`
  // to make sure we don't exceed the buffer size in non-dcheck builds.
  // See also FrameCombinerDeathTest.DebugBuildCrashesWithHighRate.
  samples_per_channel = std::min(samples_per_channel, kMaximumChannelSize);
  DeinterleavedView<float> deinterleaved(
      mixing_buffer_.data(), samples_per_channel, number_of_channels);
  MixToFloatFrame(mix_list, deinterleaved);

  if (use_limiter_) {
    RunLimiter(deinterleaved, &limiter_);
  }

  InterleaveToAudioFrame(deinterleaved, audio_frame_for_mixing);
}

}  // namespace webrtc
