Home | History | Annotate | Download | only in audio
      1 // Copyright (c) 2012 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 // Software adjust volume of samples, allows each audio stream its own
      6 // volume without impacting master volume for chrome and other applications.
      7 
      8 // Implemented as templates to allow 8, 16 and 32 bit implementations.
      9 // 8 bit is unsigned and biased by 128.
     10 
     11 // TODO(vrk): This file has been running pretty wild and free, and it's likely
     12 // that a lot of the functions can be simplified and made more elegant. Revisit
     13 // after other audio cleanup is done. (crbug.com/120319)
     14 
     15 #include "media/audio/audio_util.h"
     16 
     17 #include "base/command_line.h"
     18 #include "base/strings/string_number_conversions.h"
     19 #include "base/time/time.h"
     20 #include "media/base/media_switches.h"
     21 
     22 #if defined(OS_WIN)
     23 #include "base/win/windows_version.h"
     24 #endif
     25 
     26 namespace media {
     27 
     28 // Returns user buffer size as specified on the command line or 0 if no buffer
     29 // size has been specified.
     30 int GetUserBufferSize() {
     31   const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
     32   int buffer_size = 0;
     33   std::string buffer_size_str(cmd_line->GetSwitchValueASCII(
     34       switches::kAudioBufferSize));
     35   if (base::StringToInt(buffer_size_str, &buffer_size) && buffer_size > 0)
     36     return buffer_size;
     37 
     38   return 0;
     39 }
     40 
     41 // Computes a buffer size based on the given |sample_rate|. Must be used in
     42 // conjunction with AUDIO_PCM_LINEAR.
     43 size_t GetHighLatencyOutputBufferSize(int sample_rate) {
     44   int user_buffer_size = GetUserBufferSize();
     45   if (user_buffer_size)
     46     return user_buffer_size;
     47 
     48   // TODO(vrk/crogers): The buffer sizes that this function computes is probably
     49   // overly conservative. However, reducing the buffer size to 2048-8192 bytes
     50   // caused crbug.com/108396. This computation should be revisited while making
     51   // sure crbug.com/108396 doesn't happen again.
     52 
     53   // The minimum number of samples in a hardware packet.
     54   // This value is selected so that we can handle down to 5khz sample rate.
     55   static const size_t kMinSamplesPerHardwarePacket = 1024;
     56 
     57   // The maximum number of samples in a hardware packet.
     58   // This value is selected so that we can handle up to 192khz sample rate.
     59   static const size_t kMaxSamplesPerHardwarePacket = 64 * 1024;
     60 
     61   // This constant governs the hardware audio buffer size, this value should be
     62   // chosen carefully.
     63   // This value is selected so that we have 8192 samples for 48khz streams.
     64   static const size_t kMillisecondsPerHardwarePacket = 170;
     65 
     66   // Select the number of samples that can provide at least
     67   // |kMillisecondsPerHardwarePacket| worth of audio data.
     68   size_t samples = kMinSamplesPerHardwarePacket;
     69   while (samples <= kMaxSamplesPerHardwarePacket &&
     70          samples * base::Time::kMillisecondsPerSecond <
     71          sample_rate * kMillisecondsPerHardwarePacket) {
     72     samples *= 2;
     73   }
     74   return samples;
     75 }
     76 
     77 #if defined(OS_WIN)
     78 
     79 int NumberOfWaveOutBuffers() {
     80   // Use the user provided buffer count if provided.
     81   int buffers = 0;
     82   std::string buffers_str(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
     83       switches::kWaveOutBuffers));
     84   if (base::StringToInt(buffers_str, &buffers) && buffers > 0) {
     85     return buffers;
     86   }
     87 
     88   // Use 4 buffers for Vista, 3 for everyone else:
     89   //  - The entire Windows audio stack was rewritten for Windows Vista and wave
     90   //    out performance was degraded compared to XP.
     91   //  - The regression was fixed in Windows 7 and most configurations will work
     92   //    with 2, but some (e.g., some Sound Blasters) still need 3.
     93   //  - Some XP configurations (even multi-processor ones) also need 3.
     94   return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3;
     95 }
     96 
     97 #endif
     98 
     99 }  // namespace media
    100