1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h"
12
13namespace {
14
15void ExpectVolumeNear(int expected, int actual) {
16  // The hardware volume may be more coarsely quantized than [0, 255], so
17  // it is not always reasonable to expect to get exactly what we set. This
18  // allows for some error.
19  const int kMaxVolumeError = 10;
20  EXPECT_NEAR(expected, actual, kMaxVolumeError);
21  EXPECT_GE(actual, 0);
22  EXPECT_LE(actual, 255);
23}
24
25}  // namespace
26
27class VolumeTest : public AfterStreamingFixture {
28 public:
29  void SetAndVerifyMicVolume(unsigned int volume) {
30    bool success = voe_volume_control_->SetMicVolume(volume) == 0;
31#if !defined(WEBRTC_LINUX)
32    EXPECT_TRUE(success);
33#endif
34    if (!success) {
35      TEST_LOG("Failed to set microphone volume to %u.\n", volume);
36      return;
37    }
38
39    unsigned int test_volume = 1000;
40    success = voe_volume_control_->GetMicVolume(test_volume) == 0;
41#if !defined(WEBRTC_LINUX)
42    EXPECT_TRUE(success);
43#endif
44    if (success) {
45      EXPECT_EQ(volume, test_volume);
46    } else {
47      TEST_LOG("Failed to get the microphone volume.");
48      EXPECT_EQ(1000u, test_volume);
49    }
50  }
51
52  void SetAndVerifyInputMute(bool enable) {
53    bool success = voe_volume_control_->SetInputMute(channel_, enable) == 0;
54#if !defined(WEBRTC_LINUX)
55    EXPECT_TRUE(success);
56#endif
57    if (!success) {
58      TEST_LOG("Failed to %smute input.\n", enable ? "" : "un");
59      return;
60    }
61
62    bool is_muted = !enable;
63    success = voe_volume_control_->GetInputMute(channel_, is_muted) == 0;
64#if !defined(WEBRTC_LINUX)
65    EXPECT_TRUE(success);
66#endif
67    if (success) {
68      EXPECT_EQ(enable, is_muted);
69    } else {
70      TEST_LOG("Failed to mute the input.");
71      EXPECT_NE(enable, is_muted);
72    }
73  }
74};
75
76// Some tests are flaky on Linux (Pulse Audio), which boils down to some system
77// values not being acquired in time. In Pulse Audio we make one retry if
78// needed, but if we fail then, a -1 is returned propagating up through VoE.
79// To avoid possible bugs slipping through on other platforms we make adequate
80// changes on Linux only.
81TEST_F(VolumeTest, VerifyCorrectErrorReturns) {
82  // All tests run on correct initialization which eliminates one possible error
83  // return. In addition, we assume the audio_device returning values without
84  // error, which eliminates another potential error.
85  // Left to verify are sanity checks of set parameters.
86
87  // Valid volume range: [0, 255]
88  EXPECT_EQ(-1, voe_volume_control_->SetSpeakerVolume(256));
89  EXPECT_EQ(-1, voe_volume_control_->SetMicVolume(256));
90
91  // Valid panning rage: [0, 1]
92  EXPECT_EQ(-1, voe_volume_control_->SetOutputVolumePan(channel_, -0.1f, 0.5f));
93  EXPECT_EQ(-1, voe_volume_control_->SetOutputVolumePan(channel_, 1.1f, 0.5f));
94  EXPECT_EQ(-1, voe_volume_control_->SetOutputVolumePan(channel_, 0.5f, -0.1f));
95  EXPECT_EQ(-1, voe_volume_control_->SetOutputVolumePan(channel_, 0.5f, 1.1f));
96}
97
98TEST_F(VolumeTest, DefaultSpeakerVolumeIsAtMost255) {
99  unsigned int volume = 1000;
100  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
101  EXPECT_LE(volume, 255u);
102}
103
104TEST_F(VolumeTest, SetVolumeBeforePlayoutWorks) {
105  // This is a rather specialized test, intended to exercise some PulseAudio
106  // code. However, these conditions should be satisfied on any platform.
107  unsigned int original_volume = 0;
108  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(original_volume));
109  Sleep(1000);
110
111  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(200));
112  unsigned int volume;
113  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
114  ExpectVolumeNear(200u, volume);
115
116  PausePlaying();
117  ResumePlaying();
118  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
119  // Ensure the volume has not changed after resuming playout.
120  ExpectVolumeNear(200u, volume);
121
122  PausePlaying();
123  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(100));
124  ResumePlaying();
125  // Ensure the volume set while paused is retained.
126  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
127  ExpectVolumeNear(100u, volume);
128
129  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(original_volume));
130}
131
132TEST_F(VolumeTest, ManualSetVolumeWorks) {
133  unsigned int original_volume = 0;
134  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(original_volume));
135  Sleep(1000);
136
137  TEST_LOG("Setting speaker volume to 0 out of 255.\n");
138  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(0));
139  unsigned int volume;
140  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
141  ExpectVolumeNear(0u, volume);
142  Sleep(1000);
143
144  TEST_LOG("Setting speaker volume to 100 out of 255.\n");
145  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(100));
146  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
147  ExpectVolumeNear(100u, volume);
148  Sleep(1000);
149
150  // Set the volume to 255 very briefly so we don't blast the poor user
151  // listening to this. This is just to test the call succeeds.
152  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(255));
153  EXPECT_EQ(0, voe_volume_control_->GetSpeakerVolume(volume));
154  ExpectVolumeNear(255u, volume);
155
156  TEST_LOG("Setting speaker volume to the original %d out of 255.\n",
157      original_volume);
158  EXPECT_EQ(0, voe_volume_control_->SetSpeakerVolume(original_volume));
159  Sleep(1000);
160}
161
162TEST_F(VolumeTest, DefaultMicrophoneVolumeIsAtMost255) {
163  unsigned int volume = 1000;
164  bool could_get_mic_volume = voe_volume_control_->GetMicVolume(volume) == 0;
165#if !defined(WEBRTC_LINUX)
166  EXPECT_TRUE(could_get_mic_volume);
167#endif
168  if (could_get_mic_volume) {
169    EXPECT_LE(volume, 255u);
170  } else {
171    TEST_LOG("Failed to get the microphone volume.");
172    EXPECT_EQ(1000u, volume);
173  }
174}
175
176TEST_F(VolumeTest, ManualRequiresMicrophoneCanSetMicrophoneVolumeWithAgcOff) {
177  SwitchToManualMicrophone();
178  EXPECT_EQ(0, voe_apm_->SetAgcStatus(false));
179
180  unsigned int original_volume = 0;
181  bool could_get_mic_volume =
182      (voe_volume_control_->GetMicVolume(original_volume) == 0);
183#if !defined(WEBRTC_LINUX)
184  EXPECT_TRUE(could_get_mic_volume);
185#endif
186  if (could_get_mic_volume)
187    TEST_LOG("Current microphone volume is %u.\n", original_volume);
188  else
189    TEST_LOG("Failed to fetch current microphone volume.\n");
190
191  TEST_LOG("Setting microphone volume to 0.\n");
192  SetAndVerifyMicVolume(0);
193  Sleep(1000);
194  TEST_LOG("Setting microphone volume to 255.\n");
195  SetAndVerifyMicVolume(255);
196  Sleep(1000);
197  if (could_get_mic_volume) {
198    TEST_LOG("Setting microphone volume back to %u.\n", original_volume);
199    SetAndVerifyMicVolume(original_volume);
200    Sleep(1000);
201  }
202}
203
204TEST_F(VolumeTest, ChannelScalingIsOneByDefault) {
205  float scaling = -1.0f;
206
207  EXPECT_EQ(0, voe_volume_control_->GetChannelOutputVolumeScaling(
208      channel_, scaling));
209  EXPECT_FLOAT_EQ(1.0f, scaling);
210}
211
212TEST_F(VolumeTest, ManualCanSetChannelScaling) {
213  EXPECT_EQ(0, voe_volume_control_->SetChannelOutputVolumeScaling(
214      channel_, 0.1f));
215
216  float scaling = 1.0f;
217  EXPECT_EQ(0, voe_volume_control_->GetChannelOutputVolumeScaling(
218      channel_, scaling));
219
220  EXPECT_FLOAT_EQ(0.1f, scaling);
221
222  TEST_LOG("Channel scaling set to 0.1: audio should be barely audible.\n");
223  Sleep(2000);
224}
225
226TEST_F(VolumeTest, InputMutingIsNotEnabledByDefault) {
227  bool is_muted = true;
228  EXPECT_EQ(0, voe_volume_control_->GetInputMute(channel_, is_muted));
229  EXPECT_FALSE(is_muted);
230}
231
232TEST_F(VolumeTest, ManualInputMutingMutesMicrophone) {
233  SwitchToManualMicrophone();
234  // Enable muting.
235  SetAndVerifyInputMute(true);
236  TEST_LOG("Muted: talk into microphone and verify you can't hear yourself.\n");
237  Sleep(2000);
238
239  // Test that we can disable muting.
240  SetAndVerifyInputMute(false);
241  TEST_LOG("Unmuted: talk into microphone and verify you can hear yourself.\n");
242  Sleep(2000);
243}
244
245TEST_F(VolumeTest, ManualTestInputAndOutputLevels) {
246  SwitchToManualMicrophone();
247
248  TEST_LOG("Speak and verify that the following levels look right:\n");
249  for (int i = 0; i < 5; i++) {
250    Sleep(1000);
251    unsigned int input_level = 0;
252    unsigned int output_level = 0;
253    unsigned int input_level_full_range = 0;
254    unsigned int output_level_full_range = 0;
255
256    EXPECT_EQ(0, voe_volume_control_->GetSpeechInputLevel(
257        input_level));
258    EXPECT_EQ(0, voe_volume_control_->GetSpeechOutputLevel(
259        channel_, output_level));
260    EXPECT_EQ(0, voe_volume_control_->GetSpeechInputLevelFullRange(
261        input_level_full_range));
262    EXPECT_EQ(0, voe_volume_control_->GetSpeechOutputLevelFullRange(
263        channel_, output_level_full_range));
264
265    TEST_LOG("    warped levels (0-9)    : in=%5d, out=%5d\n",
266        input_level, output_level);
267    TEST_LOG("    linear levels (0-32768): in=%5d, out=%5d\n",
268        input_level_full_range, output_level_full_range);
269  }
270}
271
272TEST_F(VolumeTest, ChannelsAreNotPannedByDefault) {
273  float left = -1.0;
274  float right = -1.0;
275
276  EXPECT_EQ(0, voe_volume_control_->GetOutputVolumePan(channel_, left, right));
277  EXPECT_FLOAT_EQ(1.0, left);
278  EXPECT_FLOAT_EQ(1.0, right);
279}
280
281TEST_F(VolumeTest, ManualTestChannelPanning) {
282  TEST_LOG("Panning left.\n");
283  EXPECT_EQ(0, voe_volume_control_->SetOutputVolumePan(channel_, 0.8f, 0.1f));
284  Sleep(1000);
285
286  TEST_LOG("Back to center.\n");
287  EXPECT_EQ(0, voe_volume_control_->SetOutputVolumePan(channel_, 1.0f, 1.0f));
288  Sleep(1000);
289
290  TEST_LOG("Panning right.\n");
291  EXPECT_EQ(0, voe_volume_control_->SetOutputVolumePan(channel_, 0.1f, 0.8f));
292  Sleep(1000);
293
294  // To finish, verify that the getter works.
295  float left = 0.0f;
296  float right = 0.0f;
297
298  EXPECT_EQ(0, voe_volume_control_->GetOutputVolumePan(channel_, left, right));
299  EXPECT_FLOAT_EQ(0.1f, left);
300  EXPECT_FLOAT_EQ(0.8f, right);
301}
302