blob: 85e4a7d1d78a49dbe0a21a200e39da24e2954c1c [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
125TEST_F(CurrentSpeakerMonitorTest, SpeakerChange) {
126 AudioInfo info;
127 InitAudioInfo(&info, 0, 0);
128
129 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
130 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000131 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132
133 EXPECT_EQ(current_speaker_, 0U);
134 EXPECT_EQ(num_changes_, 0);
135
136 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
137 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000138 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139
140 EXPECT_EQ(current_speaker_, kSsrc2);
141 EXPECT_EQ(num_changes_, 1);
142
143 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000144 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145
146 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
147 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000148 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149
150 EXPECT_EQ(current_speaker_, kSsrc1);
151 EXPECT_EQ(num_changes_, 2);
152}
153
154TEST_F(CurrentSpeakerMonitorTest, InterwordSilence) {
155 AudioInfo info;
156 InitAudioInfo(&info, 0, 0);
157
158 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
159 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000160 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161
162 EXPECT_EQ(current_speaker_, 0U);
163 EXPECT_EQ(num_changes_, 0);
164
165 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
166 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000167 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168
169 EXPECT_EQ(current_speaker_, kSsrc2);
170 EXPECT_EQ(num_changes_, 1);
171
172 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
173 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000174 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175
176 EXPECT_EQ(current_speaker_, kSsrc2);
177 EXPECT_EQ(num_changes_, 1);
178
179 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000180 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181
182 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
183 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000184 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185
186 // Current speaker shouldn't have changed because we treat this as an inter-
187 // word silence.
188 EXPECT_EQ(current_speaker_, kSsrc2);
189 EXPECT_EQ(num_changes_, 1);
190
191 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
192 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000193 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194
195 // Current speaker shouldn't have changed because we treat this as an inter-
196 // word silence.
197 EXPECT_EQ(current_speaker_, kSsrc2);
198 EXPECT_EQ(num_changes_, 1);
199
200 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
201 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000202 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203
204 // At this point, we should have concluded that SSRC2 stopped speaking.
205 EXPECT_EQ(current_speaker_, kSsrc1);
206 EXPECT_EQ(num_changes_, 2);
207}
208
209} // namespace cricket