blob: a71f72ed8b040603993b0db2dfff6cfa5414bcbe [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander65c7f672016-02-12 00:05:01 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000011#include "webrtc/base/gunit.h"
12#include "webrtc/base/thread.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010013#include "webrtc/pc/audiomonitor.h"
14#include "webrtc/pc/currentspeakermonitor.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000015
16namespace cricket {
17
Peter Boström0c4e06b2015-10-07 12:23:21 +020018static const uint32_t kSsrc1 = 1001;
19static const uint32_t kSsrc2 = 1002;
20static const uint32_t kMinTimeBetweenSwitches = 10;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000021// Due to limited system clock resolution, the CurrentSpeakerMonitor may
22// actually require more or less time between switches than that specified
23// in the call to set_min_time_between_switches. To be safe, we sleep for
24// 90 ms more than the min time between switches before checking for a switch.
25// I am assuming system clocks do not have a coarser resolution than 90 ms.
Peter Boström0c4e06b2015-10-07 12:23:21 +020026static const uint32_t kSleepTimeBetweenSwitches = 100;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028class CurrentSpeakerMonitorTest : public testing::Test,
29 public sigslot::has_slots<> {
30 public:
31 CurrentSpeakerMonitorTest() {
deadbeefd59daf82015-10-14 15:02:44 -070032 monitor_ = new CurrentSpeakerMonitor(&source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033 // Shrink the minimum time betweeen switches to 10 ms so we don't have to
34 // slow down our tests.
35 monitor_->set_min_time_between_switches(kMinTimeBetweenSwitches);
36 monitor_->SignalUpdate.connect(this, &CurrentSpeakerMonitorTest::OnUpdate);
37 current_speaker_ = 0;
38 num_changes_ = 0;
39 monitor_->Start();
40 }
41
42 ~CurrentSpeakerMonitorTest() {
43 delete monitor_;
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000044 }
45
46 void SignalAudioMonitor(const AudioInfo& info) {
47 source_.SignalAudioMonitor(&source_, info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048 }
49
50 protected:
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000051 AudioSourceContext source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052 CurrentSpeakerMonitor* monitor_;
53 int num_changes_;
Peter Boström0c4e06b2015-10-07 12:23:21 +020054 uint32_t current_speaker_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055
Peter Boström0c4e06b2015-10-07 12:23:21 +020056 void OnUpdate(CurrentSpeakerMonitor* monitor, uint32_t current_speaker) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057 current_speaker_ = current_speaker;
58 num_changes_++;
59 }
60};
61
62static void InitAudioInfo(AudioInfo* info, int input_level, int output_level) {
63 info->input_level = input_level;
64 info->output_level = output_level;
65}
66
67TEST_F(CurrentSpeakerMonitorTest, NoActiveStreams) {
68 AudioInfo info;
69 InitAudioInfo(&info, 0, 0);
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000070 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071
72 EXPECT_EQ(current_speaker_, 0U);
73 EXPECT_EQ(num_changes_, 0);
74}
75
76TEST_F(CurrentSpeakerMonitorTest, MultipleActiveStreams) {
77 AudioInfo info;
78 InitAudioInfo(&info, 0, 0);
79
80 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
81 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000082 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083
84 // No speaker recognized because the initial sample is treated as possibly
85 // just noise and disregarded.
86 EXPECT_EQ(current_speaker_, 0U);
87 EXPECT_EQ(num_changes_, 0);
88
89 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
90 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000091 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092
93 EXPECT_EQ(current_speaker_, kSsrc2);
94 EXPECT_EQ(num_changes_, 1);
95}
96
andrew@webrtc.org44759052013-09-27 18:24:40 +000097// See: https://code.google.com/p/webrtc/issues/detail?id=2409
98TEST_F(CurrentSpeakerMonitorTest, DISABLED_RapidSpeakerChange) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099 AudioInfo info;
100 InitAudioInfo(&info, 0, 0);
101
102 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
103 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000104 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000105
106 EXPECT_EQ(current_speaker_, 0U);
107 EXPECT_EQ(num_changes_, 0);
108
109 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
110 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000111 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112
113 EXPECT_EQ(current_speaker_, kSsrc2);
114 EXPECT_EQ(num_changes_, 1);
115
116 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
117 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000118 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119
120 // We expect no speaker change because of the rapid change.
121 EXPECT_EQ(current_speaker_, kSsrc2);
122 EXPECT_EQ(num_changes_, 1);
123}
124
kjellanderb7d24f62017-02-26 22:10:14 -0800125// Flaky on iOS: webrtc:7057.
126#if defined(WEBRTC_IOS)
127#define MAYBE_SpeakerChange DISABLED_SpeakerChange
128#else
129#define MAYBE_SpeakerChange SpeakerChange
130#endif
131TEST_F(CurrentSpeakerMonitorTest, MAYBE_SpeakerChange) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132 AudioInfo info;
133 InitAudioInfo(&info, 0, 0);
134
135 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
136 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000137 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138
139 EXPECT_EQ(current_speaker_, 0U);
140 EXPECT_EQ(num_changes_, 0);
141
142 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
143 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000144 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145
146 EXPECT_EQ(current_speaker_, kSsrc2);
147 EXPECT_EQ(num_changes_, 1);
148
149 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000150 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151
152 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
153 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000154 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000155
156 EXPECT_EQ(current_speaker_, kSsrc1);
157 EXPECT_EQ(num_changes_, 2);
158}
159
160TEST_F(CurrentSpeakerMonitorTest, InterwordSilence) {
161 AudioInfo info;
162 InitAudioInfo(&info, 0, 0);
163
164 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
165 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000166 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167
168 EXPECT_EQ(current_speaker_, 0U);
169 EXPECT_EQ(num_changes_, 0);
170
171 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
172 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000173 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174
175 EXPECT_EQ(current_speaker_, kSsrc2);
176 EXPECT_EQ(num_changes_, 1);
177
178 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
179 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000180 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181
182 EXPECT_EQ(current_speaker_, kSsrc2);
183 EXPECT_EQ(num_changes_, 1);
184
185 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000186 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187
188 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
189 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000190 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000191
192 // Current speaker shouldn't have changed because we treat this as an inter-
193 // word silence.
194 EXPECT_EQ(current_speaker_, kSsrc2);
195 EXPECT_EQ(num_changes_, 1);
196
197 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
198 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000199 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200
201 // Current speaker shouldn't have changed because we treat this as an inter-
202 // word silence.
203 EXPECT_EQ(current_speaker_, kSsrc2);
204 EXPECT_EQ(num_changes_, 1);
205
206 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
207 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000208 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209
210 // At this point, we should have concluded that SSRC2 stopped speaking.
211 EXPECT_EQ(current_speaker_, kSsrc1);
212 EXPECT_EQ(num_changes_, 2);
213}
214
215} // namespace cricket