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