/*
 *  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 "voice_engine/file_player.h"

#include "common_audio/resampler/include/resampler.h"
#include "common_types.h"  // NOLINT(build/include)
#include "modules/media_file/media_file.h"
#include "modules/media_file/media_file_defines.h"
#include "rtc_base/logging.h"
#include "typedefs.h"  // NOLINT(build/include)
#include "voice_engine/coder.h"

namespace webrtc {

namespace {

class FilePlayerImpl : public FilePlayer {
 public:
  FilePlayerImpl(uint32_t instanceID, FileFormats fileFormat);
  ~FilePlayerImpl() override;

  int Get10msAudioFromFile(int16_t* outBuffer,
                           size_t* lengthInSamples,
                           int frequencyInHz) override;
  int32_t RegisterModuleFileCallback(FileCallback* callback) override;
  int32_t StartPlayingFile(const char* fileName,
                           bool loop,
                           uint32_t startPosition,
                           float volumeScaling,
                           uint32_t notification,
                           uint32_t stopPosition,
                           const CodecInst* codecInst) override;
  int32_t StartPlayingFile(InStream* sourceStream,
                           uint32_t startPosition,
                           float volumeScaling,
                           uint32_t notification,
                           uint32_t stopPosition,
                           const CodecInst* codecInst) override;
  int32_t StopPlayingFile() override;
  bool IsPlayingFile() const override;
  int32_t GetPlayoutPosition(uint32_t* durationMs) override;
  int32_t AudioCodec(CodecInst* audioCodec) const override;
  int32_t Frequency() const override;
  int32_t SetAudioScaling(float scaleFactor) override;

 private:
  int32_t SetUpAudioDecoder();

  const FileFormats _fileFormat;
  MediaFile& _fileModule;

  uint32_t _decodedLengthInMS;

  AudioCoder _audioDecoder;

  CodecInst _codec;
  int32_t _numberOf10MsPerFrame;
  int32_t _numberOf10MsInDecoder;

  Resampler _resampler;
  float _scaling;
};

FilePlayerImpl::FilePlayerImpl(const uint32_t instanceID,
                               const FileFormats fileFormat)
    : _fileFormat(fileFormat),
      _fileModule(*MediaFile::CreateMediaFile(instanceID)),
      _decodedLengthInMS(0),
      _audioDecoder(instanceID),
      _codec(),
      _numberOf10MsPerFrame(0),
      _numberOf10MsInDecoder(0),
      _resampler(),
      _scaling(1.0) {
  _codec.plfreq = 0;
}

FilePlayerImpl::~FilePlayerImpl() {
  MediaFile::DestroyMediaFile(&_fileModule);
}

int32_t FilePlayerImpl::Frequency() const {
  if (_codec.plfreq == 0) {
    return -1;
  }
  // Make sure that sample rate is 8,16 or 32 kHz. E.g. WAVE files may have
  // other sampling rates.
  if (_codec.plfreq == 11000) {
    return 16000;
  } else if (_codec.plfreq == 22000) {
    return 32000;
  } else if (_codec.plfreq == 44000) {
    return 32000;
  } else if (_codec.plfreq == 48000) {
    return 48000;
  } else {
    return _codec.plfreq;
  }
}

int32_t FilePlayerImpl::AudioCodec(CodecInst* audioCodec) const {
  *audioCodec = _codec;
  return 0;
}

int32_t FilePlayerImpl::Get10msAudioFromFile(int16_t* outBuffer,
                                             size_t* lengthInSamples,
                                             int frequencyInHz) {
  if (_codec.plfreq == 0) {
    LOG(LS_WARNING) << "Get10msAudioFromFile() playing not started!"
                    << " codec freq = " << _codec.plfreq
                    << ", wanted freq = " << frequencyInHz;
    return -1;
  }

  AudioFrame unresampledAudioFrame;
  if (STR_CASE_CMP(_codec.plname, "L16") == 0) {
    unresampledAudioFrame.sample_rate_hz_ = _codec.plfreq;

    // L16 is un-encoded data. Just pull 10 ms.
    size_t lengthInBytes = AudioFrame::kMaxDataSizeBytes;
    if (_fileModule.PlayoutAudioData(
            reinterpret_cast<int8_t*>(unresampledAudioFrame.mutable_data()),
            lengthInBytes) == -1) {
      // End of file reached.
      return -1;
    }
    if (lengthInBytes == 0) {
      *lengthInSamples = 0;
      return 0;
    }
    // One sample is two bytes.
    unresampledAudioFrame.samples_per_channel_ = lengthInBytes >> 1;

  } else {
    // Decode will generate 10 ms of audio data. PlayoutAudioData(..)
    // expects a full frame. If the frame size is larger than 10 ms,
    // PlayoutAudioData(..) data should be called proportionally less often.
    int16_t encodedBuffer[MAX_AUDIO_BUFFER_IN_SAMPLES];
    size_t encodedLengthInBytes = 0;
    if (++_numberOf10MsInDecoder >= _numberOf10MsPerFrame) {
      _numberOf10MsInDecoder = 0;
      size_t bytesFromFile = sizeof(encodedBuffer);
      if (_fileModule.PlayoutAudioData(reinterpret_cast<int8_t*>(encodedBuffer),
                                       bytesFromFile) == -1) {
        // End of file reached.
        return -1;
      }
      encodedLengthInBytes = bytesFromFile;
    }
    if (_audioDecoder.Decode(&unresampledAudioFrame, frequencyInHz,
                             reinterpret_cast<int8_t*>(encodedBuffer),
                             encodedLengthInBytes) == -1) {
      return -1;
    }
  }

  size_t outLen = 0;
  if (_resampler.ResetIfNeeded(unresampledAudioFrame.sample_rate_hz_,
                               frequencyInHz, 1)) {
    LOG(LS_WARNING) << "Get10msAudioFromFile() unexpected codec.";

    // New sampling frequency. Update state.
    outLen = static_cast<size_t>(frequencyInHz / 100);
    memset(outBuffer, 0, outLen * sizeof(int16_t));
    return 0;
  }
  _resampler.Push(unresampledAudioFrame.data(),
                  unresampledAudioFrame.samples_per_channel_, outBuffer,
                  MAX_AUDIO_BUFFER_IN_SAMPLES, outLen);

  *lengthInSamples = outLen;

  if (_scaling != 1.0) {
    for (size_t i = 0; i < outLen; i++) {
      outBuffer[i] = (int16_t)(outBuffer[i] * _scaling);
    }
  }
  _decodedLengthInMS += 10;
  return 0;
}

int32_t FilePlayerImpl::RegisterModuleFileCallback(FileCallback* callback) {
  return _fileModule.SetModuleFileCallback(callback);
}

int32_t FilePlayerImpl::SetAudioScaling(float scaleFactor) {
  if ((scaleFactor >= 0) && (scaleFactor <= 2.0)) {
    _scaling = scaleFactor;
    return 0;
  }
  LOG(LS_WARNING) << "SetAudioScaling() non-allowed scale factor.";
  return -1;
}

int32_t FilePlayerImpl::StartPlayingFile(const char* fileName,
                                         bool loop,
                                         uint32_t startPosition,
                                         float volumeScaling,
                                         uint32_t notification,
                                         uint32_t stopPosition,
                                         const CodecInst* codecInst) {
  if (_fileFormat == kFileFormatPcm16kHzFile ||
      _fileFormat == kFileFormatPcm8kHzFile ||
      _fileFormat == kFileFormatPcm32kHzFile) {
    CodecInst codecInstL16;
    strncpy(codecInstL16.plname, "L16", 32);
    codecInstL16.pltype = 93;
    codecInstL16.channels = 1;

    if (_fileFormat == kFileFormatPcm8kHzFile) {
      codecInstL16.rate = 128000;
      codecInstL16.plfreq = 8000;
      codecInstL16.pacsize = 80;
    } else if (_fileFormat == kFileFormatPcm16kHzFile) {
      codecInstL16.rate = 256000;
      codecInstL16.plfreq = 16000;
      codecInstL16.pacsize = 160;
    } else if (_fileFormat == kFileFormatPcm32kHzFile) {
      codecInstL16.rate = 512000;
      codecInstL16.plfreq = 32000;
      codecInstL16.pacsize = 320;
    } else if (_fileFormat == kFileFormatPcm48kHzFile) {
      codecInstL16.rate = 768000;
      codecInstL16.plfreq = 48000;
      codecInstL16.pacsize = 480;
    } else {
      LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
                    << "supported for PCM format.";
      return -1;
    }

    if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                          _fileFormat, &codecInstL16,
                                          startPosition, stopPosition) == -1) {
      LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
                      << "pcm file " << fileName;
      return -1;
    }
    SetAudioScaling(volumeScaling);
  } else if (_fileFormat == kFileFormatPreencodedFile) {
    if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                          _fileFormat, codecInst) == -1) {
      LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
                      << "pre-encoded file " << fileName;
      return -1;
    }
  } else {
    CodecInst* no_inst = NULL;
    if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                          _fileFormat, no_inst, startPosition,
                                          stopPosition) == -1) {
      LOG(LS_WARNING) << "StartPlayingFile() failed to initialize file "
                      << fileName;
      return -1;
    }
    SetAudioScaling(volumeScaling);
  }
  if (SetUpAudioDecoder() == -1) {
    StopPlayingFile();
    return -1;
  }
  return 0;
}

int32_t FilePlayerImpl::StartPlayingFile(InStream* sourceStream,
                                         uint32_t startPosition,
                                         float volumeScaling,
                                         uint32_t notification,
                                         uint32_t stopPosition,
                                         const CodecInst* codecInst) {
  if (_fileFormat == kFileFormatPcm16kHzFile ||
      _fileFormat == kFileFormatPcm32kHzFile ||
      _fileFormat == kFileFormatPcm8kHzFile ||
      _fileFormat == kFileFormatPcm48kHzFile) {
    CodecInst codecInstL16;
    strncpy(codecInstL16.plname, "L16", 32);
    codecInstL16.pltype = 93;
    codecInstL16.channels = 1;

    if (_fileFormat == kFileFormatPcm8kHzFile) {
      codecInstL16.rate = 128000;
      codecInstL16.plfreq = 8000;
      codecInstL16.pacsize = 80;
    } else if (_fileFormat == kFileFormatPcm16kHzFile) {
      codecInstL16.rate = 256000;
      codecInstL16.plfreq = 16000;
      codecInstL16.pacsize = 160;
    } else if (_fileFormat == kFileFormatPcm32kHzFile) {
      codecInstL16.rate = 512000;
      codecInstL16.plfreq = 32000;
      codecInstL16.pacsize = 320;
    } else if (_fileFormat == kFileFormatPcm48kHzFile) {
      codecInstL16.rate = 768000;
      codecInstL16.plfreq = 48000;
      codecInstL16.pacsize = 480;
    } else {
      LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
                    << "supported for PCM format.";
      return -1;
    }
    if (_fileModule.StartPlayingAudioStream(
            *sourceStream, notification, _fileFormat, &codecInstL16,
            startPosition, stopPosition) == -1) {
      LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
                    << "playout.";
      return -1;
    }

  } else if (_fileFormat == kFileFormatPreencodedFile) {
    if (_fileModule.StartPlayingAudioStream(*sourceStream, notification,
                                            _fileFormat, codecInst) == -1) {
      LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
                    << "playout.";
      return -1;
    }
  } else {
    CodecInst* no_inst = NULL;
    if (_fileModule.StartPlayingAudioStream(*sourceStream, notification,
                                            _fileFormat, no_inst, startPosition,
                                            stopPosition) == -1) {
      LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
                    << "playout.";
      return -1;
    }
  }
  SetAudioScaling(volumeScaling);

  if (SetUpAudioDecoder() == -1) {
    StopPlayingFile();
    return -1;
  }
  return 0;
}

int32_t FilePlayerImpl::StopPlayingFile() {
  memset(&_codec, 0, sizeof(CodecInst));
  _numberOf10MsPerFrame = 0;
  _numberOf10MsInDecoder = 0;
  return _fileModule.StopPlaying();
}

bool FilePlayerImpl::IsPlayingFile() const {
  return _fileModule.IsPlaying();
}

int32_t FilePlayerImpl::GetPlayoutPosition(uint32_t* durationMs) {
  return _fileModule.PlayoutPositionMs(*durationMs);
}

int32_t FilePlayerImpl::SetUpAudioDecoder() {
  if ((_fileModule.codec_info(_codec) == -1)) {
    LOG(LS_WARNING) << "Failed to retrieve codec info of file data.";
    return -1;
  }
  if (STR_CASE_CMP(_codec.plname, "L16") != 0 &&
      _audioDecoder.SetDecodeCodec(_codec) == -1) {
    LOG(LS_WARNING) << "SetUpAudioDecoder() codec " << _codec.plname
                    << " not supported.";
    return -1;
  }
  _numberOf10MsPerFrame = _codec.pacsize / (_codec.plfreq / 100);
  _numberOf10MsInDecoder = 0;
  return 0;
}

}  // namespace

std::unique_ptr<FilePlayer> FilePlayer::CreateFilePlayer(
    uint32_t instanceID,
    FileFormats fileFormat) {
  switch (fileFormat) {
    case kFileFormatWavFile:
    case kFileFormatCompressedFile:
    case kFileFormatPreencodedFile:
    case kFileFormatPcm16kHzFile:
    case kFileFormatPcm8kHzFile:
    case kFileFormatPcm32kHzFile:
    case kFileFormatPcm48kHzFile:
      // audio formats
      return std::unique_ptr<FilePlayer>(
          new FilePlayerImpl(instanceID, fileFormat));
    default:
      assert(false);
      return nullptr;
  }
}

}  // namespace webrtc
