blob: fa3f0cb7d92a6caacf3ea7dea6e84cf7316045b2 [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
Steve Anton36b29d12017-10-30 09:57:42 -070011#include <utility>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "pc/currentspeakermonitor.h"
14#include "pc/audiomonitor.h"
15#include "rtc_base/gunit.h"
16#include "rtc_base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017
18namespace cricket {
19
Peter Boström0c4e06b2015-10-07 12:23:21 +020020static const uint32_t kSsrc1 = 1001;
21static const uint32_t kSsrc2 = 1002;
22static const uint32_t kMinTimeBetweenSwitches = 10;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023// Due to limited system clock resolution, the CurrentSpeakerMonitor may
24// actually require more or less time between switches than that specified
25// in the call to set_min_time_between_switches. To be safe, we sleep for
26// 90 ms more than the min time between switches before checking for a switch.
27// I am assuming system clocks do not have a coarser resolution than 90 ms.
Peter Boström0c4e06b2015-10-07 12:23:21 +020028static const uint32_t kSleepTimeBetweenSwitches = 100;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000029
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030class CurrentSpeakerMonitorTest : public testing::Test,
31 public sigslot::has_slots<> {
32 public:
33 CurrentSpeakerMonitorTest() {
deadbeefd59daf82015-10-14 15:02:44 -070034 monitor_ = new CurrentSpeakerMonitor(&source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035 // Shrink the minimum time betweeen switches to 10 ms so we don't have to
36 // slow down our tests.
37 monitor_->set_min_time_between_switches(kMinTimeBetweenSwitches);
38 monitor_->SignalUpdate.connect(this, &CurrentSpeakerMonitorTest::OnUpdate);
39 current_speaker_ = 0;
40 num_changes_ = 0;
41 monitor_->Start();
42 }
43
44 ~CurrentSpeakerMonitorTest() {
45 delete monitor_;
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000046 }
47
48 void SignalAudioMonitor(const AudioInfo& info) {
49 source_.SignalAudioMonitor(&source_, info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050 }
51
52 protected:
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000053 AudioSourceContext source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 CurrentSpeakerMonitor* monitor_;
55 int num_changes_;
Peter Boström0c4e06b2015-10-07 12:23:21 +020056 uint32_t current_speaker_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057
Peter Boström0c4e06b2015-10-07 12:23:21 +020058 void OnUpdate(CurrentSpeakerMonitor* monitor, uint32_t current_speaker) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059 current_speaker_ = current_speaker;
60 num_changes_++;
61 }
62};
63
64static void InitAudioInfo(AudioInfo* info, int input_level, int output_level) {
65 info->input_level = input_level;
66 info->output_level = output_level;
67}
68
69TEST_F(CurrentSpeakerMonitorTest, NoActiveStreams) {
70 AudioInfo info;
71 InitAudioInfo(&info, 0, 0);
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000072 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073
74 EXPECT_EQ(current_speaker_, 0U);
75 EXPECT_EQ(num_changes_, 0);
76}
77
78TEST_F(CurrentSpeakerMonitorTest, MultipleActiveStreams) {
79 AudioInfo info;
80 InitAudioInfo(&info, 0, 0);
81
82 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
83 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000084 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085
86 // No speaker recognized because the initial sample is treated as possibly
87 // just noise and disregarded.
88 EXPECT_EQ(current_speaker_, 0U);
89 EXPECT_EQ(num_changes_, 0);
90
91 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
92 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000093 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094
95 EXPECT_EQ(current_speaker_, kSsrc2);
96 EXPECT_EQ(num_changes_, 1);
97}
98
andrew@webrtc.org44759052013-09-27 18:24:40 +000099// See: https://code.google.com/p/webrtc/issues/detail?id=2409
100TEST_F(CurrentSpeakerMonitorTest, DISABLED_RapidSpeakerChange) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101 AudioInfo info;
102 InitAudioInfo(&info, 0, 0);
103
104 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
105 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000106 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107
108 EXPECT_EQ(current_speaker_, 0U);
109 EXPECT_EQ(num_changes_, 0);
110
111 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
112 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000113 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114
115 EXPECT_EQ(current_speaker_, kSsrc2);
116 EXPECT_EQ(num_changes_, 1);
117
118 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
119 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000120 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121
122 // We expect no speaker change because of the rapid change.
123 EXPECT_EQ(current_speaker_, kSsrc2);
124 EXPECT_EQ(num_changes_, 1);
125}
126
kjellanderb7d24f62017-02-26 22:10:14 -0800127// Flaky on iOS: webrtc:7057.
128#if defined(WEBRTC_IOS)
129#define MAYBE_SpeakerChange DISABLED_SpeakerChange
130#else
131#define MAYBE_SpeakerChange SpeakerChange
132#endif
133TEST_F(CurrentSpeakerMonitorTest, MAYBE_SpeakerChange) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134 AudioInfo info;
135 InitAudioInfo(&info, 0, 0);
136
137 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
138 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000139 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140
141 EXPECT_EQ(current_speaker_, 0U);
142 EXPECT_EQ(num_changes_, 0);
143
144 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
145 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000146 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147
148 EXPECT_EQ(current_speaker_, kSsrc2);
149 EXPECT_EQ(num_changes_, 1);
150
151 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000152 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153
154 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
155 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000156 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157
158 EXPECT_EQ(current_speaker_, kSsrc1);
159 EXPECT_EQ(num_changes_, 2);
160}
161
162TEST_F(CurrentSpeakerMonitorTest, InterwordSilence) {
163 AudioInfo info;
164 InitAudioInfo(&info, 0, 0);
165
166 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
167 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000168 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169
170 EXPECT_EQ(current_speaker_, 0U);
171 EXPECT_EQ(num_changes_, 0);
172
173 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
174 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000175 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176
177 EXPECT_EQ(current_speaker_, kSsrc2);
178 EXPECT_EQ(num_changes_, 1);
179
180 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
181 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000182 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000183
184 EXPECT_EQ(current_speaker_, kSsrc2);
185 EXPECT_EQ(num_changes_, 1);
186
187 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000188 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189
190 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
191 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000192 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193
194 // Current speaker shouldn't have changed because we treat this as an inter-
195 // word silence.
196 EXPECT_EQ(current_speaker_, kSsrc2);
197 EXPECT_EQ(num_changes_, 1);
198
199 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
200 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000201 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202
203 // Current speaker shouldn't have changed because we treat this as an inter-
204 // word silence.
205 EXPECT_EQ(current_speaker_, kSsrc2);
206 EXPECT_EQ(num_changes_, 1);
207
208 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
209 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000210 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211
212 // At this point, we should have concluded that SSRC2 stopped speaking.
213 EXPECT_EQ(current_speaker_, kSsrc1);
214 EXPECT_EQ(num_changes_, 2);
215}
216
217} // namespace cricket