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.
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 "media/audio/audio_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
15 #include "base/win/scoped_com_initializer.h"
16 #include "media/audio/win/core_audio_util_win.h"
21 double GetVolumeAfterSetVolumeOnLinux(AudioInputStream
* ais
,
22 double target_volume
) {
23 // SetVolume() is asynchronous on Linux, we need to keep trying until
24 // the SetVolume() operation is done.
25 static const int kTimesToRun
= 10;
27 for (int i
= 0; i
< kTimesToRun
; ++i
) {
28 volume
= ais
->GetVolume();
29 if (volume
== target_volume
)
32 // Sleep 100ms to wait for the operation.
33 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
39 class AudioInputVolumeTest
: public ::testing::Test
{
41 AudioInputVolumeTest()
42 : audio_manager_(AudioManager::Create())
44 , com_init_(base::win::ScopedCOMInitializer::kMTA
)
49 bool CanRunAudioTests() {
51 // TODO(henrika): add support for volume control on Windows XP as well.
52 // For now, we might as well signal false already here to avoid running
53 // these tests on Windows XP.
54 if (!CoreAudioUtil::IsSupported())
57 if (!audio_manager_
.get())
60 return audio_manager_
->HasAudioInputDevices();
63 // Helper method which checks if the stream has volume support.
64 bool HasDeviceVolumeControl(AudioInputStream
* stream
) {
68 return (stream
->GetMaxVolume() != 0.0);
71 AudioInputStream
* CreateAndOpenStream(const std::string
& device_id
) {
72 const AudioParameters
& params
=
73 audio_manager_
->GetInputStreamParameters(device_id
);
74 AudioInputStream
* ais
= audio_manager_
->MakeAudioInputStream(
76 EXPECT_TRUE(NULL
!= ais
);
78 #if defined(OS_LINUX) || defined(OS_OPENBSD)
79 // Some linux devices do not support our settings, we may fail to open
82 // Default device should always be able to be opened.
83 EXPECT_TRUE(AudioManagerBase::kDefaultDeviceId
!= device_id
);
87 #elif defined(OS_WIN) || defined(OS_MACOSX)
88 EXPECT_TRUE(ais
->Open());
94 scoped_ptr
<AudioManager
> audio_manager_
;
97 base::win::ScopedCOMInitializer com_init_
;
101 TEST_F(AudioInputVolumeTest
, InputVolumeTest
) {
102 if (!CanRunAudioTests())
105 // Retrieve a list of all available input devices.
106 AudioDeviceNames device_names
;
107 audio_manager_
->GetAudioInputDeviceNames(&device_names
);
108 if (device_names
.empty()) {
109 LOG(WARNING
) << "Could not find any available input device";
113 // Scan all available input devices and repeat the same test for all of them.
114 for (AudioDeviceNames::const_iterator it
= device_names
.begin();
115 it
!= device_names
.end();
117 AudioInputStream
* ais
= CreateAndOpenStream(it
->unique_id
);
119 DLOG(WARNING
) << "Failed to open stream for device " << it
->unique_id
;
123 if (!HasDeviceVolumeControl(ais
)) {
124 DLOG(WARNING
) << "Device: " << it
->unique_id
125 << ", does not have volume control.";
130 double max_volume
= ais
->GetMaxVolume();
131 EXPECT_GT(max_volume
, 0.0);
133 // Store the current input-device volume level.
134 double original_volume
= ais
->GetVolume();
135 EXPECT_GE(original_volume
, 0.0);
136 #if defined(OS_WIN) || defined(OS_MACOSX)
137 // Note that |original_volume| can be higher than |max_volume| on Linux.
138 EXPECT_LE(original_volume
, max_volume
);
141 // Set the volume to the maxiumum level..
142 ais
->SetVolume(max_volume
);
143 double current_volume
= ais
->GetVolume();
144 EXPECT_EQ(max_volume
, current_volume
);
146 // Set the volume to the mininum level (=0).
147 double new_volume
= 0.0;
148 ais
->SetVolume(new_volume
);
149 #if defined(OS_LINUX)
150 current_volume
= GetVolumeAfterSetVolumeOnLinux(ais
, new_volume
);
152 current_volume
= ais
->GetVolume();
154 EXPECT_EQ(new_volume
, current_volume
);
156 // Set the volume to the mid level (50% of max).
157 // Verify that the absolute error is small enough.
158 new_volume
= max_volume
/ 2;
159 ais
->SetVolume(new_volume
);
160 #if defined(OS_LINUX)
161 current_volume
= GetVolumeAfterSetVolumeOnLinux(ais
, new_volume
);
163 current_volume
= ais
->GetVolume();
165 EXPECT_LT(current_volume
, max_volume
);
166 EXPECT_GT(current_volume
, 0);
167 EXPECT_NEAR(current_volume
, new_volume
, 0.25 * max_volume
);
169 // Restores the volume to the original value.
170 ais
->SetVolume(original_volume
);
171 current_volume
= ais
->GetVolume();
172 EXPECT_EQ(original_volume
, current_volume
);