audio_input_volume_unittest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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#include <cmath> 6 7#include "base/logging.h" 8#include "base/memory/scoped_ptr.h" 9#include "media/audio/audio_io.h" 10#include "media/audio/audio_manager_base.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13#if defined(OS_WIN) 14#include "base/win/scoped_com_initializer.h" 15#include "media/audio/win/core_audio_util_win.h" 16#endif 17 18namespace media { 19 20double GetVolumeAfterSetVolumeOnLinux(AudioInputStream* ais, 21 double target_volume) { 22 // SetVolume() is asynchronous on Linux, we need to keep trying until 23 // the SetVolume() operation is done. 24 static const int kTimesToRun = 10; 25 double volume = 0.0; 26 for (int i = 0; i < kTimesToRun; ++i) { 27 volume = ais->GetVolume(); 28 if (volume == target_volume) 29 break; 30 31 // Sleep 100ms to wait for the operation. 32 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 33 } 34 35 return volume; 36} 37 38class AudioInputVolumeTest : public ::testing::Test { 39 protected: 40 AudioInputVolumeTest() 41 : audio_manager_(AudioManager::Create()) 42#if defined(OS_WIN) 43 , com_init_(base::win::ScopedCOMInitializer::kMTA) 44#endif 45 { 46 } 47 48 bool CanRunAudioTests() { 49#if defined(OS_WIN) 50 // TODO(henrika): add support for volume control on Windows XP as well. 51 // For now, we might as well signal false already here to avoid running 52 // these tests on Windows XP. 53 if (!CoreAudioUtil::IsSupported()) 54 return false; 55#endif 56 if (!audio_manager_) 57 return false; 58 59 return audio_manager_->HasAudioInputDevices(); 60 } 61 62 // Helper method which checks if the stream has volume support. 63 bool HasDeviceVolumeControl(AudioInputStream* stream) { 64 if (!stream) 65 return false; 66 67 return (stream->GetMaxVolume() != 0.0); 68 } 69 70 AudioInputStream* CreateAndOpenStream(const std::string& device_id) { 71 const AudioParameters& params = 72 audio_manager_->GetInputStreamParameters(device_id); 73 AudioInputStream* ais = audio_manager_->MakeAudioInputStream( 74 params, device_id); 75 EXPECT_TRUE(NULL != ais); 76 77#if defined(OS_LINUX) || defined(OS_OPENBSD) 78 // Some linux devices do not support our settings, we may fail to open 79 // those devices. 80 if (!ais->Open()) { 81 // Default device should always be able to be opened. 82 EXPECT_TRUE(AudioManagerBase::kDefaultDeviceId != device_id); 83 ais->Close(); 84 ais = NULL; 85 } 86#elif defined(OS_WIN) || defined(OS_MACOSX) 87 EXPECT_TRUE(ais->Open()); 88#endif 89 90 return ais; 91 } 92 93 scoped_ptr<AudioManager> audio_manager_; 94 95#if defined(OS_WIN) 96 base::win::ScopedCOMInitializer com_init_; 97#endif 98}; 99 100#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 101// Currently failing on linux ARM bot: http://crbug/238490 102#define MAYBE_InputVolumeTest DISABLED_InputVolumeTest 103#else 104#define MAYBE_InputVolumeTest InputVolumeTest 105#endif 106 107TEST_F(AudioInputVolumeTest, MAYBE_InputVolumeTest) { 108 if (!CanRunAudioTests()) 109 return; 110 111 // Retrieve a list of all available input devices. 112 AudioDeviceNames device_names; 113 audio_manager_->GetAudioInputDeviceNames(&device_names); 114 if (device_names.empty()) { 115 LOG(WARNING) << "Could not find any available input device"; 116 return; 117 } 118 119 // Scan all available input devices and repeat the same test for all of them. 120 for (AudioDeviceNames::const_iterator it = device_names.begin(); 121 it != device_names.end(); 122 ++it) { 123 AudioInputStream* ais = CreateAndOpenStream(it->unique_id); 124 if (!ais) { 125 DLOG(WARNING) << "Failed to open stream for device " << it->unique_id; 126 continue; 127 } 128 129 if (!HasDeviceVolumeControl(ais)) { 130 DLOG(WARNING) << "Device: " << it->unique_id 131 << ", does not have volume control."; 132 ais->Close(); 133 continue; 134 } 135 136 double max_volume = ais->GetMaxVolume(); 137 EXPECT_GT(max_volume, 0.0); 138 139 // Store the current input-device volume level. 140 double original_volume = ais->GetVolume(); 141 EXPECT_GE(original_volume, 0.0); 142#if defined(OS_WIN) || defined(OS_MACOSX) 143 // Note that |original_volume| can be higher than |max_volume| on Linux. 144 EXPECT_LE(original_volume, max_volume); 145#endif 146 147 // Set the volume to the maxiumum level.. 148 ais->SetVolume(max_volume); 149 double current_volume = ais->GetVolume(); 150 EXPECT_EQ(max_volume, current_volume); 151 152 // Set the volume to the mininum level (=0). 153 double new_volume = 0.0; 154 ais->SetVolume(new_volume); 155#if defined(OS_LINUX) 156 current_volume = GetVolumeAfterSetVolumeOnLinux(ais, new_volume); 157#else 158 current_volume = ais->GetVolume(); 159#endif 160 EXPECT_EQ(new_volume, current_volume); 161 162 // Set the volume to the mid level (50% of max). 163 // Verify that the absolute error is small enough. 164 new_volume = max_volume / 2; 165 ais->SetVolume(new_volume); 166#if defined(OS_LINUX) 167 current_volume = GetVolumeAfterSetVolumeOnLinux(ais, new_volume); 168#else 169 current_volume = ais->GetVolume(); 170#endif 171 EXPECT_LT(current_volume, max_volume); 172 EXPECT_GT(current_volume, 0); 173 EXPECT_NEAR(current_volume, new_volume, 0.25 * max_volume); 174 175 // Restores the volume to the original value. 176 ais->SetVolume(original_volume); 177 current_volume = ais->GetVolume(); 178 EXPECT_EQ(original_volume, current_volume); 179 180 ais->Close(); 181 } 182} 183 184} // namespace media 185