// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/shared_impl/ppb_audio_config_shared.h"

#include <algorithm>

#include "build/build_config.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_instance_api.h"

namespace ppapi {

// Rounds up requested_size to the nearest multiple of minimum_size.
static uint32_t CalculateMultipleOfSampleFrameCount(uint32_t minimum_size,
                                                    uint32_t requested_size) {
  const uint32_t multiple = (requested_size + minimum_size - 1) / minimum_size;
  return std::min(minimum_size * multiple,
                  static_cast<uint32_t>(PP_AUDIOMAXSAMPLEFRAMECOUNT));
}

PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type,
                                               PP_Instance instance)
    : Resource(type, instance),
      sample_rate_(PP_AUDIOSAMPLERATE_NONE),
      sample_frame_count_(0) {}

PPB_AudioConfig_Shared::~PPB_AudioConfig_Shared() {}

PP_Resource PPB_AudioConfig_Shared::Create(ResourceObjectType type,
                                           PP_Instance instance,
                                           PP_AudioSampleRate sample_rate,
                                           uint32_t sample_frame_count) {
  scoped_refptr<PPB_AudioConfig_Shared> object(
      new PPB_AudioConfig_Shared(type, instance));
  if (!object->Init(sample_rate, sample_frame_count))
    return 0;
  return object->GetReference();
}

// static
uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_0(
    PP_AudioSampleRate sample_rate,
    uint32_t requested_sample_frame_count) {
  // Version 1.0: Don't actually query to get a value from the
  // hardware; instead return the input for in-range values.
  if (requested_sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
    return PP_AUDIOMINSAMPLEFRAMECOUNT;
  if (requested_sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT)
    return PP_AUDIOMAXSAMPLEFRAMECOUNT;
  return requested_sample_frame_count;
}

// static
uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_1(
    PP_Instance instance,
    PP_AudioSampleRate sample_rate,
    uint32_t sample_frame_count) {
  // Version 1.1: Query the back-end hardware for sample rate and buffer size,
  // and recommend a best fit based on request.
  thunk::EnterInstanceNoLock enter(instance);
  if (enter.failed())
    return 0;

  // Get the hardware config.
  PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>(
      enter.functions()->GetAudioHardwareOutputSampleRate(instance));
  uint32_t hardware_sample_frame_count =
      enter.functions()->GetAudioHardwareOutputBufferSize(instance);
  if (sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
    sample_frame_count = PP_AUDIOMINSAMPLEFRAMECOUNT;

  // If hardware information isn't available we're connected to a fake audio
  // output stream on the browser side, so we can use whatever sample count the
  // client wants.
  if (!hardware_sample_frame_count || !hardware_sample_rate)
    return sample_frame_count;

  // Note: All the values below were determined through experimentation to
  // minimize jitter and back-to-back callbacks from the browser.  Please take
  // care when modifying these values as they impact a large number of users.
  // TODO(dalecurtis): Land jitter test and add documentation for updating this.

  // Should track the value reported by XP and ALSA backends.
  const uint32_t kHighLatencySampleFrameCount = 2048;
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
  // TODO(ihf): Remove this once ARM Chromebooks support low latency audio. For
  // now we classify them as high latency. See crbug.com/289770. Note that
  // Adobe Flash is affected but not HTML5, WebRTC and WebAudio (they are using
  // real time threads).
  const bool kHighLatencyDevice = true;
#else
  const bool kHighLatencyDevice = false;
#endif

  // If client is using same sample rate as audio hardware, then recommend a
  // multiple of the audio hardware's sample frame count.
  if (!kHighLatencyDevice && hardware_sample_rate == sample_rate) {
    return CalculateMultipleOfSampleFrameCount(hardware_sample_frame_count,
                                               sample_frame_count);
  }

  // If the hardware requires a high latency buffer or we're at a low sample
  // rate w/ a buffer that's larger than 10ms, choose the nearest multiple of
  // the high latency sample frame count.  An example of too low and too large
  // is 16kHz and a sample frame count greater than 160 frames.
  if (kHighLatencyDevice ||
      hardware_sample_frame_count >= kHighLatencySampleFrameCount ||
      (hardware_sample_rate < 44100 &&
       hardware_sample_frame_count > hardware_sample_rate / 100u)) {
    return CalculateMultipleOfSampleFrameCount(
        sample_frame_count,
        std::max(kHighLatencySampleFrameCount, hardware_sample_frame_count));
  }

  // All low latency clients should be able to handle a 512 frame buffer with
  // resampling from 44.1kHz and 48kHz to higher sample rates.
  // TODO(dalecurtis): We may need to investigate making the callback thread
  // high priority to handle buffers at the absolute minimum w/o glitching.
  const uint32_t kLowLatencySampleFrameCount = 512;

  // Special case for 48kHz -> 44.1kHz and buffer sizes greater than 10ms.  In
  // testing most buffer sizes > 10ms led to glitching, so we choose a size we
  // know won't cause jitter.
  int min_sample_frame_count = kLowLatencySampleFrameCount;
  if (hardware_sample_rate == 44100 && sample_rate == 48000 &&
      hardware_sample_frame_count > hardware_sample_rate / 100u) {
    min_sample_frame_count =
        std::max(2 * kLowLatencySampleFrameCount, hardware_sample_frame_count);
  }

  return CalculateMultipleOfSampleFrameCount(min_sample_frame_count,
                                             sample_frame_count);
}

// static
PP_AudioSampleRate PPB_AudioConfig_Shared::RecommendSampleRate(
    PP_Instance instance) {
  thunk::EnterInstanceNoLock enter(instance);
  if (enter.failed())
    return PP_AUDIOSAMPLERATE_NONE;
  PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>(
      enter.functions()->GetAudioHardwareOutputSampleRate(instance));
  return hardware_sample_rate;
}

thunk::PPB_AudioConfig_API* PPB_AudioConfig_Shared::AsPPB_AudioConfig_API() {
  return this;
}

PP_AudioSampleRate PPB_AudioConfig_Shared::GetSampleRate() {
  return sample_rate_;
}

uint32_t PPB_AudioConfig_Shared::GetSampleFrameCount() {
  return sample_frame_count_;
}

bool PPB_AudioConfig_Shared::Init(PP_AudioSampleRate sample_rate,
                                  uint32_t sample_frame_count) {
  // TODO(brettw): Currently we don't actually check what the hardware
  // supports, so just allow sample rates of the "guaranteed working" ones.
  // TODO(dalecurtis): If sample rates are added RecommendSampleFrameCount_1_1()
  // must be updated to account for the new rates.
  if (sample_rate != PP_AUDIOSAMPLERATE_44100 &&
      sample_rate != PP_AUDIOSAMPLERATE_48000)
    return false;

  // TODO(brettw): Currently we don't actually query to get a value from the
  // hardware, so just validate the range.
  if (sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT ||
      sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
    return false;

  sample_rate_ = sample_rate;
  sample_frame_count_ = sample_frame_count;
  return true;
}

}  // namespace ppapi
