/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "media/base/shell_audio_bus.h"

#include <algorithm>
#include <limits>

namespace media {

namespace {

const float kFloat32ToInt16Factor = 32768.f;

inline void ConvertSample(ShellAudioBus::SampleType src_type,
                          const uint8* src_ptr,
                          ShellAudioBus::SampleType dest_type,
                          uint8* dest_ptr) {
  if (src_type == dest_type) {
    memcpy(dest_ptr, src_ptr,
           src_type == ShellAudioBus::kInt16 ? sizeof(int16) : sizeof(float));
  } else if (src_type == ShellAudioBus::kFloat32) {
    float sample_in_float = *reinterpret_cast<const float*>(src_ptr);
    int32 sample_in_int32 =
        static_cast<int32>(sample_in_float * kFloat32ToInt16Factor);
    sample_in_int32 =
        std::max<int32>(sample_in_int32, std::numeric_limits<int16>::min());
    sample_in_int32 =
        std::min<int32>(sample_in_int32, std::numeric_limits<int16>::max());
    *reinterpret_cast<int16*>(dest_ptr) = static_cast<int16>(sample_in_int32);
  } else {
    int16 sample = *reinterpret_cast<const int16*>(src_ptr);
    *reinterpret_cast<float*>(dest_ptr) =
        static_cast<float>(sample) / kFloat32ToInt16Factor;
  }
}

}  // namespace

ShellAudioBus::ShellAudioBus(size_t channels, size_t frames,
                             SampleType sample_type, StorageType storage_type)
    : channels_(channels),
      frames_(frames),
      sample_type_(sample_type),
      storage_type_(storage_type) {
  DCHECK_GT(channels_, 0);

  if (storage_type_ == kInterleaved) {
    data_.reset(static_cast<uint8*>(base::AlignedAlloc(
        GetSampleSizeInBytes() * frames * channels, kChannelAlignmentInBytes)));
    channel_data_.push_back(data_.get());
  } else {
    DCHECK_EQ(storage_type_, kPlanar);
    size_t aligned_per_channel_size_in_bytes =
        (GetSampleSizeInBytes() * frames + kChannelAlignmentInBytes - 1) /
        kChannelAlignmentInBytes * kChannelAlignmentInBytes;
    data_.reset(static_cast<uint8*>(
        base::AlignedAlloc(aligned_per_channel_size_in_bytes * channels,
                           kChannelAlignmentInBytes)));
    channel_data_.reserve(channels);
    for (size_t i = 0; i < channels_; ++i) {
      channel_data_.push_back(data_.get() +
                              aligned_per_channel_size_in_bytes * i);
    }
  }
}

ShellAudioBus::ShellAudioBus(size_t frames, const std::vector<float*>& samples)
    : channels_(samples.size()),
      frames_(frames),
      sample_type_(kFloat32),
      storage_type_(kPlanar) {
  DCHECK_GT(channels_, 0);

  channel_data_.reserve(samples.size());
  for (size_t i = 0; i < samples.size(); ++i) {
    channel_data_.push_back(reinterpret_cast<uint8*>(samples[i]));
  }
}

ShellAudioBus::ShellAudioBus(size_t channels, size_t frames, float* samples)
    : channels_(channels),
      frames_(frames),
      sample_type_(kFloat32),
      storage_type_(kInterleaved) {
  DCHECK_GT(channels_, 0);

  channel_data_.push_back(reinterpret_cast<uint8*>(samples));
}

ShellAudioBus::ShellAudioBus(size_t frames, const std::vector<int16*>& samples)
    : channels_(samples.size()),
      frames_(frames),
      sample_type_(kInt16),
      storage_type_(kPlanar) {
  DCHECK_GT(channels_, 0);

  channel_data_.reserve(samples.size());
  for (size_t i = 0; i < samples.size(); ++i) {
    channel_data_.push_back(reinterpret_cast<uint8*>(samples[i]));
  }
}

ShellAudioBus::ShellAudioBus(size_t channels, size_t frames, int16* samples)
    : channels_(channels),
      frames_(frames),
      sample_type_(kInt16),
      storage_type_(kInterleaved) {
  DCHECK_GT(channels_, 0);

  channel_data_.push_back(reinterpret_cast<uint8*>(samples));
}

size_t ShellAudioBus::GetSampleSizeInBytes() const {
  if (sample_type_ == kInt16) {
    return sizeof(int16);
  }
  DCHECK_EQ(sample_type_, kFloat32);
  return sizeof(float);
}

const uint8* ShellAudioBus::interleaved_data() const {
  DCHECK_EQ(storage_type_, kInterleaved);
  return channel_data_[0];
}

const uint8* ShellAudioBus::planar_data(size_t channel) const {
  DCHECK_LT(channel, channels_);
  DCHECK_EQ(storage_type_, kPlanar);
  return channel_data_[channel];
}

void ShellAudioBus::ZeroFrames(size_t start_frame, size_t end_frame) {
  DCHECK_LE(start_frame, end_frame);
  DCHECK_LE(end_frame, frames_);
  end_frame = std::min(end_frame, frames_);
  start_frame = std::min(start_frame, end_frame);
  if (start_frame >= end_frame) {
    return;
  }
  if (storage_type_ == kInterleaved) {
    memset(GetSamplePtr(0, start_frame), 0,
           GetSampleSizeInBytes() * (end_frame - start_frame) * channels_);
  } else {
    for (size_t channel = 0; channel < channels_; ++channel) {
      memset(GetSamplePtr(channel, start_frame), 0,
             GetSampleSizeInBytes() * (end_frame - start_frame));
    }
  }
}

void ShellAudioBus::Assign(const ShellAudioBus& source) {
  DCHECK_EQ(channels_, source.channels_);
  if (channels_ != source.channels_) {
    ZeroAllFrames();
    return;
  }

  if (sample_type_ == source.sample_type_ &&
      storage_type_ == source.storage_type_) {
    size_t frames = std::min(frames_, source.frames_);
    if (storage_type_ == kInterleaved) {
      memcpy(GetSamplePtr(0, 0), source.GetSamplePtr(0, 0),
             GetSampleSizeInBytes() * frames * channels_);
    } else {
      for (size_t channel = 0; channel < channels_; ++channel) {
        memcpy(GetSamplePtr(channel, 0), source.GetSamplePtr(channel, 0),
               GetSampleSizeInBytes() * frames);
      }
    }
    return;
  }

  size_t frames = std::min(frames_, source.frames_);
  for (size_t channel = 0; channel < channels_; ++channel) {
    for (size_t frame = 0; frame < frames; ++frame) {
      ConvertSample(source.sample_type_, source.GetSamplePtr(channel, frame),
                    sample_type_, GetSamplePtr(channel, frame));
    }
  }
}

void ShellAudioBus::Assign(const ShellAudioBus& source,
                           const std::vector<float>& matrix) {
  DCHECK_EQ(channels() * source.channels(), matrix.size());
  DCHECK_EQ(sample_type_, kFloat32);
  DCHECK_EQ(source.sample_type_, kFloat32);
  if (channels() * source.channels() != matrix.size() ||
      sample_type_ != kFloat32 || source.sample_type_ != kFloat32) {
    ZeroAllFrames();
    return;
  }

  size_t frames = std::min(frames_, source.frames_);
  for (size_t dest_channel = 0; dest_channel < channels_; ++dest_channel) {
    for (size_t frame = 0; frame < frames; ++frame) {
      float mixed_sample = 0.f;
      for (size_t src_channel = 0; src_channel < source.channels_;
           ++src_channel) {
        mixed_sample += source.GetFloat32Sample(src_channel, frame) *
                        matrix[dest_channel * source.channels_ + src_channel];
      }
      SetFloat32Sample(dest_channel, frame, mixed_sample);
    }
  }
}

template <ShellAudioBus::StorageType T>
inline uint8* ShellAudioBus::GetSamplePtrForType(size_t channel,
                                                 size_t frame) const {
  DCHECK_LT(channel, channels_);
  DCHECK_LT(frame, frames_);

  if (T == kInterleaved) {
    return channel_data_[0] + sizeof(float) * (channels_ * frame + channel);
  } else if (T == kPlanar) {
    return channel_data_[channel] + sizeof(float) * frame;
  } else {
    NOTREACHED();
  }

  return NULL;
}

template <ShellAudioBus::StorageType T>
inline float ShellAudioBus::GetFloat32SampleForType(size_t channel,
                                                    size_t frame) const {
  return *reinterpret_cast<const float*>(
      GetSamplePtrForType<T>(channel, frame));
}

template <ShellAudioBus::StorageType SourceStorageType,
          ShellAudioBus::StorageType DestStorageType>
void ShellAudioBus::MixForType(const ShellAudioBus& source) {
  const size_t frames = std::min(frames_, source.frames_);

  for (size_t channel = 0; channel < channels_; ++channel) {
    for (size_t frame = 0; frame < frames; ++frame) {
      *reinterpret_cast<float*>(
          GetSamplePtrForType<DestStorageType>(channel, frame)) +=
          source.GetFloat32SampleForType<SourceStorageType>(channel, frame);
    }
  }
}

void ShellAudioBus::Mix(const ShellAudioBus& source) {
  DCHECK_EQ(channels_, source.channels_);
  DCHECK_EQ(sample_type_, kFloat32);
  DCHECK_EQ(source.sample_type_, kFloat32);
  if (channels_ != source.channels_ || sample_type_ != kFloat32 ||
      source.sample_type_ != kFloat32) {
    ZeroAllFrames();
    return;
  }

  // Profiling has identified this area of code as hot, so instead of calling
  // GetSamplePtr, which branches on storage_type_ each time it is called, we
  // branch once before we loop and inline the branch of the function we want.
  DCHECK_EQ(GetSampleSizeInBytes(), sizeof(float));
  if (source.storage_type_ == kInterleaved && storage_type_ == kInterleaved) {
    MixForType<kInterleaved, kInterleaved>(source);
  } else if (source.storage_type_ == kInterleaved && storage_type_ == kPlanar) {
    MixForType<kInterleaved, kPlanar>(source);
  } else if (source.storage_type_ == kPlanar && storage_type_ == kInterleaved) {
    MixForType<kPlanar, kInterleaved>(source);
  } else if (source.storage_type_ == kPlanar && storage_type_ == kPlanar) {
    MixForType<kPlanar, kPlanar>(source);
  } else {
    NOTREACHED();
  }
}

void ShellAudioBus::Mix(const ShellAudioBus& source,
                        const std::vector<float>& matrix) {
  DCHECK_EQ(channels() * source.channels(), matrix.size());
  DCHECK_EQ(sample_type_, kFloat32);
  DCHECK_EQ(source.sample_type_, kFloat32);
  if (channels() * source.channels() != matrix.size() ||
      sample_type_ != kFloat32 || source.sample_type_ != kFloat32) {
    ZeroAllFrames();
    return;
  }

  size_t frames = std::min(frames_, source.frames_);
  for (size_t dest_channel = 0; dest_channel < channels_; ++dest_channel) {
    for (size_t frame = 0; frame < frames; ++frame) {
      float mixed_sample = 0.f;
      for (size_t src_channel = 0; src_channel < source.channels_;
           ++src_channel) {
        mixed_sample += source.GetFloat32Sample(src_channel, frame) *
                        matrix[dest_channel * source.channels_ + src_channel];
      }
      mixed_sample += GetFloat32Sample(dest_channel, frame);
      SetFloat32Sample(dest_channel, frame, mixed_sample);
    }
  }
}

uint8* ShellAudioBus::GetSamplePtr(size_t channel, size_t frame) {
  DCHECK_LT(channel, channels_);
  DCHECK_LT(frame, frames_);

  if (storage_type_ == kInterleaved) {
    return channel_data_[0] +
           GetSampleSizeInBytes() * (channels_ * frame + channel);
  } else {
    return channel_data_[channel] + GetSampleSizeInBytes() * frame;
  }
}

const uint8* ShellAudioBus::GetSamplePtr(size_t channel, size_t frame) const {
  DCHECK_LT(channel, channels_);
  DCHECK_LT(frame, frames_);

  if (storage_type_ == kInterleaved) {
    return channel_data_[0] +
           GetSampleSizeInBytes() * (channels_ * frame + channel);
  } else {
    return channel_data_[channel] + GetSampleSizeInBytes() * frame;
  }
}

}  // namespace media
