Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/base/audio_hardware_config.h"
      6 
      7 #include <algorithm>
      8 #include <cmath>
      9 
     10 #include "base/logging.h"
     11 #include "build/build_config.h"
     12 
     13 using base::AutoLock;
     14 using media::AudioParameters;
     15 
     16 namespace media {
     17 
     18 #if !defined(OS_WIN)
     19 // Taken from "Bit Twiddling Hacks"
     20 // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
     21 static uint32_t RoundUpToPowerOfTwo(uint32_t v) {
     22   v--;
     23   v |= v >> 1;
     24   v |= v >> 2;
     25   v |= v >> 4;
     26   v |= v >> 8;
     27   v |= v >> 16;
     28   v++;
     29   return v;
     30 }
     31 #endif
     32 
     33 AudioHardwareConfig::AudioHardwareConfig(
     34     const AudioParameters& input_params,
     35     const AudioParameters& output_params)
     36     : input_params_(input_params),
     37       output_params_(output_params) {}
     38 
     39 AudioHardwareConfig::~AudioHardwareConfig() {}
     40 
     41 int AudioHardwareConfig::GetOutputBufferSize() const {
     42   AutoLock auto_lock(config_lock_);
     43   return output_params_.frames_per_buffer();
     44 }
     45 
     46 int AudioHardwareConfig::GetOutputSampleRate() const {
     47   AutoLock auto_lock(config_lock_);
     48   return output_params_.sample_rate();
     49 }
     50 
     51 ChannelLayout AudioHardwareConfig::GetOutputChannelLayout() const {
     52   AutoLock auto_lock(config_lock_);
     53   return output_params_.channel_layout();
     54 }
     55 
     56 int AudioHardwareConfig::GetOutputChannels() const {
     57   AutoLock auto_lock(config_lock_);
     58   return output_params_.channels();
     59 }
     60 
     61 int AudioHardwareConfig::GetInputSampleRate() const {
     62   AutoLock auto_lock(config_lock_);
     63   return input_params_.sample_rate();
     64 }
     65 
     66 ChannelLayout AudioHardwareConfig::GetInputChannelLayout() const {
     67   AutoLock auto_lock(config_lock_);
     68   return input_params_.channel_layout();
     69 }
     70 
     71 int AudioHardwareConfig::GetInputChannels() const {
     72   AutoLock auto_lock(config_lock_);
     73   return input_params_.channels();
     74 }
     75 
     76 media::AudioParameters
     77 AudioHardwareConfig::GetInputConfig() const {
     78   AutoLock auto_lock(config_lock_);
     79   return input_params_;
     80 }
     81 
     82 media::AudioParameters
     83 AudioHardwareConfig::GetOutputConfig() const {
     84   AutoLock auto_lock(config_lock_);
     85   return output_params_;
     86 }
     87 
     88 void AudioHardwareConfig::UpdateInputConfig(
     89     const AudioParameters& input_params) {
     90   AutoLock auto_lock(config_lock_);
     91   input_params_ = input_params;
     92 }
     93 
     94 void AudioHardwareConfig::UpdateOutputConfig(
     95     const AudioParameters& output_params) {
     96   AutoLock auto_lock(config_lock_);
     97   output_params_ = output_params;
     98 }
     99 
    100 int AudioHardwareConfig::GetHighLatencyBufferSize() const {
    101   AutoLock auto_lock(config_lock_);
    102 
    103   // Empirically, we consider 20ms of samples to be high latency.
    104   const double twenty_ms_size = 2.0 * output_params_.sample_rate() / 100;
    105 
    106 #if defined(OS_WIN)
    107   // Windows doesn't use power of two buffer sizes, so we should always round up
    108   // to the nearest multiple of the output buffer size.
    109   const int high_latency_buffer_size =
    110       std::ceil(twenty_ms_size / output_params_.frames_per_buffer()) *
    111       output_params_.frames_per_buffer();
    112 #else
    113   // On other platforms use the nearest higher power of two buffer size.  For a
    114   // given sample rate, this works out to:
    115   //
    116   //     <= 3200   : 64
    117   //     <= 6400   : 128
    118   //     <= 12800  : 256
    119   //     <= 25600  : 512
    120   //     <= 51200  : 1024
    121   //     <= 102400 : 2048
    122   //     <= 204800 : 4096
    123   //
    124   // On Linux, the minimum hardware buffer size is 512, so the lower calculated
    125   // values are unused.  OSX may have a value as low as 128.
    126   const int high_latency_buffer_size = RoundUpToPowerOfTwo(twenty_ms_size);
    127 #endif  // defined(OS_WIN)
    128 
    129   return std::max(output_params_.frames_per_buffer(), high_latency_buffer_size);
    130 }
    131 
    132 }  // namespace media
    133