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

#include "webrtc/base/logging.h"
#include "webrtc/common_audio/resampler/include/resampler.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/media_file/media_file.h"
#include "webrtc/modules/media_file/media_file_defines.h"
#include "webrtc/typedefs.h"
#include "webrtc/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 32000;
  } 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 = sizeof(unresampledAudioFrame.data_);
    if (_fileModule.PlayoutAudioData(
            reinterpret_cast<int8_t*>(unresampledAudioFrame.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 = 160;
    } 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) {
    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 = 160;
    } 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:
      // audio formats
      return std::unique_ptr<FilePlayer>(
          new FilePlayerImpl(instanceID, fileFormat));
    default:
      assert(false);
      return nullptr;
  }
}

}  // namespace webrtc
