// Copyright 2017 The Cobalt Authors. 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 "starboard/configuration.h"
#include "starboard/log.h"
#include "starboard/shared/starboard/player/filter/audio_resampler.h"
#include "starboard/shared/starboard/player/filter/interleaved_sinc_resampler.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {

namespace {

// CPU based simple AudioResampler implementation.  Note that it currently only
// supports resample audio between same storage type and same channels but with
// different sample types.
class AudioResamplerImpl : public AudioResampler {
 public:
  AudioResamplerImpl(SbMediaAudioSampleType source_sample_type,
                     SbMediaAudioFrameStorageType source_storage_type,
                     int source_sample_rate,
                     SbMediaAudioSampleType destination_sample_type,
                     SbMediaAudioFrameStorageType destination_storage_type,
                     int destination_sample_rate,
                     int channels)
      : source_sample_type_(source_sample_type),
        source_storage_type_(source_storage_type),
        destination_sample_type_(destination_sample_type),
        destination_storage_type_(destination_storage_type),
        interleaved_resampler_(static_cast<double>(source_sample_rate) /
                                   static_cast<double>(destination_sample_rate),
                               channels) {}

  scoped_refptr<DecodedAudio> Resample(
      const scoped_refptr<DecodedAudio>& buffer) override;

  scoped_refptr<DecodedAudio> WriteEndOfStream() override;

 private:
  InterleavedSincResampler interleaved_resampler_;

  SbMediaAudioSampleType source_sample_type_;
  SbMediaAudioFrameStorageType source_storage_type_;
  SbMediaAudioSampleType destination_sample_type_;
  SbMediaAudioFrameStorageType destination_storage_type_;
};

}  // namespace

// static
scoped_ptr<AudioResampler> AudioResampler::Create(
    SbMediaAudioSampleType source_sample_type,
    SbMediaAudioFrameStorageType source_storage_type,
    int source_sample_rate,
    SbMediaAudioSampleType destination_sample_type,
    SbMediaAudioFrameStorageType destination_storage_type,
    int destination_sample_rate,
    int channels) {
  return scoped_ptr<AudioResampler>(new AudioResamplerImpl(
      source_sample_type, source_storage_type, source_sample_rate,
      destination_sample_type, destination_storage_type,
      destination_sample_rate, channels));
}

scoped_refptr<DecodedAudio> AudioResamplerImpl::WriteEndOfStream() {
  int out_num_of_frames = interleaved_resampler_.GetNumberOfCashedFrames();
  if (out_num_of_frames > 0) {
    int channels = interleaved_resampler_.channels();
    int resampled_audio_size = out_num_of_frames * channels * sizeof(float);
    scoped_refptr<DecodedAudio> resampled_audio = new DecodedAudio(
        channels, kSbMediaAudioSampleTypeFloat32,
        kSbMediaAudioFrameStorageTypeInterleaved, 0, resampled_audio_size);

    float* dst = reinterpret_cast<float*>(resampled_audio->buffer());
    interleaved_resampler_.Resample(dst, out_num_of_frames);

    resampled_audio->SwitchFormatTo(destination_sample_type_,
                                    destination_storage_type_);
    return resampled_audio;
  }

  return new DecodedAudio;
}

scoped_refptr<DecodedAudio> AudioResamplerImpl::Resample(
    const scoped_refptr<DecodedAudio>& audio_data) {
  SB_DCHECK(audio_data->channels() == interleaved_resampler_.channels());

  // It does nothing if source sample type is float and source storage type is
  // interleaved.
  audio_data->SwitchFormatTo(kSbMediaAudioSampleTypeFloat32,
                             kSbMediaAudioFrameStorageTypeInterleaved);

  int num_of_frames = audio_data->frames();
  int channels = audio_data->channels();
  int out_num_of_frames = static_cast<int>(
      ceil(num_of_frames / interleaved_resampler_.GetSampleRateRatio()));

  int resampled_audio_size = out_num_of_frames * channels * sizeof(float);

  scoped_refptr<DecodedAudio> resampled_audio = nullptr;

  float* samples = reinterpret_cast<float*>(audio_data->buffer());
  interleaved_resampler_.QueueBuffer(samples, num_of_frames);

  if (interleaved_resampler_.HasEnoughData(out_num_of_frames)) {
    resampled_audio =
        new DecodedAudio(channels, kSbMediaAudioSampleTypeFloat32,
                         kSbMediaAudioFrameStorageTypeInterleaved,
                         audio_data->timestamp(), resampled_audio_size);
    float* dst = reinterpret_cast<float*>(resampled_audio->buffer());
    interleaved_resampler_.Resample(dst, out_num_of_frames);

    resampled_audio->SwitchFormatTo(destination_sample_type_,
                                    destination_storage_type_);
  }

  return resampled_audio;
}

}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
