blob: 41e2f8d633502c287a689e0044bd07930e9faef5 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000028#include "webrtc/base/gunit.h"
29#include "webrtc/base/thread.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010030#include "webrtc/pc/audiomonitor.h"
31#include "webrtc/pc/currentspeakermonitor.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
33namespace cricket {
34
Peter Boström0c4e06b2015-10-07 12:23:21 +020035static const uint32_t kSsrc1 = 1001;
36static const uint32_t kSsrc2 = 1002;
37static const uint32_t kMinTimeBetweenSwitches = 10;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038// Due to limited system clock resolution, the CurrentSpeakerMonitor may
39// actually require more or less time between switches than that specified
40// in the call to set_min_time_between_switches. To be safe, we sleep for
41// 90 ms more than the min time between switches before checking for a switch.
42// I am assuming system clocks do not have a coarser resolution than 90 ms.
Peter Boström0c4e06b2015-10-07 12:23:21 +020043static const uint32_t kSleepTimeBetweenSwitches = 100;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045class CurrentSpeakerMonitorTest : public testing::Test,
46 public sigslot::has_slots<> {
47 public:
48 CurrentSpeakerMonitorTest() {
deadbeefd59daf82015-10-14 15:02:44 -070049 monitor_ = new CurrentSpeakerMonitor(&source_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050 // Shrink the minimum time betweeen switches to 10 ms so we don't have to
51 // slow down our tests.
52 monitor_->set_min_time_between_switches(kMinTimeBetweenSwitches);
53 monitor_->SignalUpdate.connect(this, &CurrentSpeakerMonitorTest::OnUpdate);
54 current_speaker_ = 0;
55 num_changes_ = 0;
56 monitor_->Start();
57 }
58
59 ~CurrentSpeakerMonitorTest() {
60 delete monitor_;
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000061 }
62
63 void SignalAudioMonitor(const AudioInfo& info) {
64 source_.SignalAudioMonitor(&source_, info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 }
66
67 protected:
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000068 AudioSourceContext source_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 CurrentSpeakerMonitor* monitor_;
70 int num_changes_;
Peter Boström0c4e06b2015-10-07 12:23:21 +020071 uint32_t current_speaker_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072
Peter Boström0c4e06b2015-10-07 12:23:21 +020073 void OnUpdate(CurrentSpeakerMonitor* monitor, uint32_t current_speaker) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 current_speaker_ = current_speaker;
75 num_changes_++;
76 }
77};
78
79static void InitAudioInfo(AudioInfo* info, int input_level, int output_level) {
80 info->input_level = input_level;
81 info->output_level = output_level;
82}
83
84TEST_F(CurrentSpeakerMonitorTest, NoActiveStreams) {
85 AudioInfo info;
86 InitAudioInfo(&info, 0, 0);
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000087 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088
89 EXPECT_EQ(current_speaker_, 0U);
90 EXPECT_EQ(num_changes_, 0);
91}
92
93TEST_F(CurrentSpeakerMonitorTest, MultipleActiveStreams) {
94 AudioInfo info;
95 InitAudioInfo(&info, 0, 0);
96
97 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
98 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +000099 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100
101 // No speaker recognized because the initial sample is treated as possibly
102 // just noise and disregarded.
103 EXPECT_EQ(current_speaker_, 0U);
104 EXPECT_EQ(num_changes_, 0);
105
106 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
107 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000108 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000109
110 EXPECT_EQ(current_speaker_, kSsrc2);
111 EXPECT_EQ(num_changes_, 1);
112}
113
andrew@webrtc.org44759052013-09-27 18:24:40 +0000114// See: https://code.google.com/p/webrtc/issues/detail?id=2409
115TEST_F(CurrentSpeakerMonitorTest, DISABLED_RapidSpeakerChange) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116 AudioInfo info;
117 InitAudioInfo(&info, 0, 0);
118
119 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
120 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000121 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122
123 EXPECT_EQ(current_speaker_, 0U);
124 EXPECT_EQ(num_changes_, 0);
125
126 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
127 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000128 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129
130 EXPECT_EQ(current_speaker_, kSsrc2);
131 EXPECT_EQ(num_changes_, 1);
132
133 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
134 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000135 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136
137 // We expect no speaker change because of the rapid change.
138 EXPECT_EQ(current_speaker_, kSsrc2);
139 EXPECT_EQ(num_changes_, 1);
140}
141
142TEST_F(CurrentSpeakerMonitorTest, SpeakerChange) {
143 AudioInfo info;
144 InitAudioInfo(&info, 0, 0);
145
146 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
147 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
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_, 0U);
151 EXPECT_EQ(num_changes_, 0);
152
153 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
154 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000155 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000156
157 EXPECT_EQ(current_speaker_, kSsrc2);
158 EXPECT_EQ(num_changes_, 1);
159
160 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000161 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162
163 info.active_streams.push_back(std::make_pair(kSsrc1, 9));
164 info.active_streams.push_back(std::make_pair(kSsrc2, 1));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000165 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166
167 EXPECT_EQ(current_speaker_, kSsrc1);
168 EXPECT_EQ(num_changes_, 2);
169}
170
171TEST_F(CurrentSpeakerMonitorTest, InterwordSilence) {
172 AudioInfo info;
173 InitAudioInfo(&info, 0, 0);
174
175 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
176 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000177 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000178
179 EXPECT_EQ(current_speaker_, 0U);
180 EXPECT_EQ(num_changes_, 0);
181
182 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
183 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000184 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185
186 EXPECT_EQ(current_speaker_, kSsrc2);
187 EXPECT_EQ(num_changes_, 1);
188
189 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
190 info.active_streams.push_back(std::make_pair(kSsrc2, 7));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000191 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192
193 EXPECT_EQ(current_speaker_, kSsrc2);
194 EXPECT_EQ(num_changes_, 1);
195
196 // Wait so the changes don't come so rapidly.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000197 rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000198
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 // Current speaker shouldn't have changed because we treat this as an inter-
213 // word silence.
214 EXPECT_EQ(current_speaker_, kSsrc2);
215 EXPECT_EQ(num_changes_, 1);
216
217 info.active_streams.push_back(std::make_pair(kSsrc1, 3));
218 info.active_streams.push_back(std::make_pair(kSsrc2, 0));
pthatcher@webrtc.org4c0544a2014-12-19 22:29:55 +0000219 SignalAudioMonitor(info);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220
221 // At this point, we should have concluded that SSRC2 stopped speaking.
222 EXPECT_EQ(current_speaker_, kSsrc1);
223 EXPECT_EQ(num_changes_, 2);
224}
225
226} // namespace cricket