blob: 672c5626f9be30886d8f2ac30f17ae0706e8a1ec [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2010 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
28#ifndef TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
29#define TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
30
31#include <list>
32#include <map>
33#include <vector>
34
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035#include "talk/media/base/codec.h"
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +000036#include "talk/media/base/rtputils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037#include "talk/media/webrtc/fakewebrtccommon.h"
38#include "talk/media/webrtc/webrtcvoe.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000039#include "webrtc/base/basictypes.h"
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +020040#include "webrtc/base/checks.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000041#include "webrtc/base/gunit.h"
42#include "webrtc/base/stringutils.h"
Henrik Lundin64dad832015-05-11 12:44:23 +020043#include "webrtc/config.h"
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +000044#include "webrtc/modules/audio_processing/include/audio_processing.h"
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +000045
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046namespace cricket {
47
48// Function returning stats will return these values
49// for all values based on type.
50const int kIntStatValue = 123;
51const float kFractionLostStatValue = 0.5;
52
53static const char kFakeDefaultDeviceName[] = "Fake Default";
54static const int kFakeDefaultDeviceId = -1;
55static const char kFakeDeviceName[] = "Fake Device";
56#ifdef WIN32
57static const int kFakeDeviceId = 0;
58#else
59static const int kFakeDeviceId = 1;
60#endif
61
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +000062static const int kOpusBandwidthNb = 4000;
63static const int kOpusBandwidthMb = 6000;
64static const int kOpusBandwidthWb = 8000;
65static const int kOpusBandwidthSwb = 12000;
66static const int kOpusBandwidthFb = 20000;
67
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +000068static const webrtc::NetworkStatistics kNetStats = {
69 1, // uint16_t currentBufferSize;
70 2, // uint16_t preferredBufferSize;
71 true, // bool jitterPeaksFound;
72 1234, // uint16_t currentPacketLossRate;
73 567, // uint16_t currentDiscardRate;
74 8901, // uint16_t currentExpandRate;
75 234, // uint16_t currentSpeechExpandRate;
76 5678, // uint16_t currentPreemptiveRate;
77 9012, // uint16_t currentAccelerateRate;
78 3456, // uint16_t currentSecondaryDecodedRate;
79 7890, // int32_t clockDriftPPM;
80 54, // meanWaitingTimeMs;
81 32, // int medianWaitingTimeMs;
82 1, // int minWaitingTimeMs;
83 98, // int maxWaitingTimeMs;
84 7654, // int addedSamples;
85}; // These random but non-trivial numbers are used for testing.
86
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +020087#define WEBRTC_CHECK_CHANNEL(channel) \
88 if (channels_.find(channel) == channels_.end()) return -1;
89
90#define WEBRTC_ASSERT_CHANNEL(channel) \
henrikg91d6ede2015-09-17 00:24:34 -070091 RTC_DCHECK(channels_.find(channel) != channels_.end());
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +020092
henrike@webrtc.org79047f92014-03-06 23:46:59 +000093// Verify the header extension ID, if enabled, is within the bounds specified in
94// [RFC5285]: 1-14 inclusive.
95#define WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id) \
96 do { \
97 if (enable && (id < 1 || id > 14)) { \
98 return -1; \
99 } \
100 } while (0);
101
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000102class FakeAudioProcessing : public webrtc::AudioProcessing {
103 public:
104 FakeAudioProcessing() : experimental_ns_enabled_(false) {}
105
106 WEBRTC_STUB(Initialize, ())
107 WEBRTC_STUB(Initialize, (
108 int input_sample_rate_hz,
109 int output_sample_rate_hz,
110 int reverse_sample_rate_hz,
111 webrtc::AudioProcessing::ChannelLayout input_layout,
112 webrtc::AudioProcessing::ChannelLayout output_layout,
113 webrtc::AudioProcessing::ChannelLayout reverse_layout));
Michael Graczyk86c6d332015-07-23 11:41:39 -0700114 WEBRTC_STUB(Initialize, (
115 const webrtc::ProcessingConfig& processing_config));
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000116
117 WEBRTC_VOID_FUNC(SetExtraOptions, (const webrtc::Config& config)) {
118 experimental_ns_enabled_ = config.Get<webrtc::ExperimentalNs>().enabled;
119 }
120
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000121 WEBRTC_STUB_CONST(proc_sample_rate_hz, ());
122 WEBRTC_STUB_CONST(proc_split_sample_rate_hz, ());
123 WEBRTC_STUB_CONST(num_input_channels, ());
124 WEBRTC_STUB_CONST(num_output_channels, ());
125 WEBRTC_STUB_CONST(num_reverse_channels, ());
126 WEBRTC_VOID_STUB(set_output_will_be_muted, (bool muted));
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000127 WEBRTC_STUB(ProcessStream, (webrtc::AudioFrame* frame));
128 WEBRTC_STUB(ProcessStream, (
129 const float* const* src,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700130 size_t samples_per_channel,
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000131 int input_sample_rate_hz,
132 webrtc::AudioProcessing::ChannelLayout input_layout,
133 int output_sample_rate_hz,
134 webrtc::AudioProcessing::ChannelLayout output_layout,
135 float* const* dest));
Michael Graczyk86c6d332015-07-23 11:41:39 -0700136 WEBRTC_STUB(ProcessStream,
137 (const float* const* src,
138 const webrtc::StreamConfig& input_config,
139 const webrtc::StreamConfig& output_config,
140 float* const* dest));
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000141 WEBRTC_STUB(AnalyzeReverseStream, (webrtc::AudioFrame* frame));
ekmeyerson60d9b332015-08-14 10:35:55 -0700142 WEBRTC_STUB(ProcessReverseStream, (webrtc::AudioFrame * frame));
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000143 WEBRTC_STUB(AnalyzeReverseStream, (
144 const float* const* data,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700145 size_t samples_per_channel,
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000146 int sample_rate_hz,
147 webrtc::AudioProcessing::ChannelLayout layout));
ekmeyerson60d9b332015-08-14 10:35:55 -0700148 WEBRTC_STUB(ProcessReverseStream,
149 (const float* const* src,
150 const webrtc::StreamConfig& reverse_input_config,
151 const webrtc::StreamConfig& reverse_output_config,
152 float* const* dest));
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000153 WEBRTC_STUB(set_stream_delay_ms, (int delay));
154 WEBRTC_STUB_CONST(stream_delay_ms, ());
155 WEBRTC_BOOL_STUB_CONST(was_stream_delay_set, ());
156 WEBRTC_VOID_STUB(set_stream_key_pressed, (bool key_pressed));
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000157 WEBRTC_VOID_STUB(set_delay_offset_ms, (int offset));
158 WEBRTC_STUB_CONST(delay_offset_ms, ());
159 WEBRTC_STUB(StartDebugRecording, (const char filename[kMaxFilenameSize]));
160 WEBRTC_STUB(StartDebugRecording, (FILE* handle));
161 WEBRTC_STUB(StopDebugRecording, ());
Bjorn Volcker4e7aa432015-07-07 11:50:05 +0200162 WEBRTC_VOID_STUB(UpdateHistogramsOnCallEnd, ());
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000163 webrtc::EchoCancellation* echo_cancellation() const override { return NULL; }
164 webrtc::EchoControlMobile* echo_control_mobile() const override {
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000165 return NULL;
166 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000167 webrtc::GainControl* gain_control() const override { return NULL; }
168 webrtc::HighPassFilter* high_pass_filter() const override { return NULL; }
169 webrtc::LevelEstimator* level_estimator() const override { return NULL; }
170 webrtc::NoiseSuppression* noise_suppression() const override { return NULL; }
171 webrtc::VoiceDetection* voice_detection() const override { return NULL; }
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000172
173 bool experimental_ns_enabled() {
174 return experimental_ns_enabled_;
175 }
176
177 private:
178 bool experimental_ns_enabled_;
179};
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000180
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181class FakeWebRtcVoiceEngine
182 : public webrtc::VoEAudioProcessing,
183 public webrtc::VoEBase, public webrtc::VoECodec, public webrtc::VoEDtmf,
Fredrik Solenberg7d173362015-09-23 12:23:21 +0200184 public webrtc::VoEHardware, public webrtc::VoENetEqStats,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185 public webrtc::VoENetwork, public webrtc::VoERTP_RTCP,
186 public webrtc::VoEVideoSync, public webrtc::VoEVolumeControl {
187 public:
188 struct DtmfInfo {
189 DtmfInfo()
190 : dtmf_event_code(-1),
191 dtmf_out_of_band(false),
192 dtmf_length_ms(-1) {}
193 int dtmf_event_code;
194 bool dtmf_out_of_band;
195 int dtmf_length_ms;
196 };
197 struct Channel {
buildbot@webrtc.orgaf6640f2014-04-28 21:31:51 +0000198 explicit Channel()
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 : external_transport(false),
200 send(false),
201 playout(false),
202 volume_scale(1.0),
203 volume_pan_left(1.0),
204 volume_pan_right(1.0),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 vad(false),
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000206 codec_fec(false),
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +0000207 max_encoding_bandwidth(0),
minyue@webrtc.org9b2e1142015-03-13 09:38:07 +0000208 opus_dtx(false),
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000209 red(false),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 nack(false),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000211 rx_agc_enabled(false),
212 rx_agc_mode(webrtc::kAgcDefault),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213 cn8_type(13),
214 cn16_type(105),
215 dtmf_type(106),
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000216 red_type(117),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217 nack_max_packets(0),
218 send_ssrc(0),
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000219 send_audio_level_ext_(-1),
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000220 receive_audio_level_ext_(-1),
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000221 send_absolute_sender_time_ext_(-1),
Henrik Lundin64dad832015-05-11 12:44:23 +0200222 receive_absolute_sender_time_ext_(-1),
Minyue2013aec2015-05-13 14:14:42 +0200223 associate_send_channel(-1),
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200224 neteq_capacity(-1),
225 neteq_fast_accelerate(false) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 memset(&send_codec, 0, sizeof(send_codec));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000227 memset(&rx_agc_config, 0, sizeof(rx_agc_config));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 }
229 bool external_transport;
230 bool send;
231 bool playout;
232 float volume_scale;
233 float volume_pan_left;
234 float volume_pan_right;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 bool vad;
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000236 bool codec_fec;
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +0000237 int max_encoding_bandwidth;
minyue@webrtc.org9b2e1142015-03-13 09:38:07 +0000238 bool opus_dtx;
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000239 bool red;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 bool nack;
wu@webrtc.org97077a32013-10-25 21:18:33 +0000241 bool rx_agc_enabled;
242 webrtc::AgcModes rx_agc_mode;
243 webrtc::AgcConfig rx_agc_config;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244 int cn8_type;
245 int cn16_type;
246 int dtmf_type;
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000247 int red_type;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 int nack_max_packets;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200249 uint32_t send_ssrc;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000250 int send_audio_level_ext_;
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000251 int receive_audio_level_ext_;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000252 int send_absolute_sender_time_ext_;
253 int receive_absolute_sender_time_ext_;
Minyue2013aec2015-05-13 14:14:42 +0200254 int associate_send_channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 DtmfInfo dtmf_info;
256 std::vector<webrtc::CodecInst> recv_codecs;
257 webrtc::CodecInst send_codec;
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000258 webrtc::PacketTime last_rtp_packet_time;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 std::list<std::string> packets;
Henrik Lundin64dad832015-05-11 12:44:23 +0200260 int neteq_capacity;
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200261 bool neteq_fast_accelerate;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 };
263
264 FakeWebRtcVoiceEngine(const cricket::AudioCodec* const* codecs,
265 int num_codecs)
266 : inited_(false),
267 last_channel_(-1),
268 fail_create_channel_(false),
269 codecs_(codecs),
270 num_codecs_(num_codecs),
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000271 num_set_send_codecs_(0),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 ec_enabled_(false),
273 ec_metrics_enabled_(false),
274 cng_enabled_(false),
275 ns_enabled_(false),
276 agc_enabled_(false),
277 highpass_filter_enabled_(false),
278 stereo_swapping_enabled_(false),
279 typing_detection_enabled_(false),
280 ec_mode_(webrtc::kEcDefault),
281 aecm_mode_(webrtc::kAecmSpeakerphone),
282 ns_mode_(webrtc::kNsDefault),
283 agc_mode_(webrtc::kAgcDefault),
284 observer_(NULL),
285 playout_fail_channel_(-1),
286 send_fail_channel_(-1),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000287 recording_sample_rate_(-1),
Fredrik Solenberg7d173362015-09-23 12:23:21 +0200288 playout_sample_rate_(-1) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289 memset(&agc_config_, 0, sizeof(agc_config_));
290 }
291 ~FakeWebRtcVoiceEngine() {
292 // Ought to have all been deleted by the WebRtcVoiceMediaChannel
293 // destructors, but just in case ...
294 for (std::map<int, Channel*>::const_iterator i = channels_.begin();
295 i != channels_.end(); ++i) {
296 delete i->second;
297 }
298 }
299
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000300 bool IsInited() const { return inited_; }
301 int GetLastChannel() const { return last_channel_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200302 int GetChannelFromLocalSsrc(uint32_t local_ssrc) const {
wu@webrtc.org9dba5252013-08-05 20:36:57 +0000303 for (std::map<int, Channel*>::const_iterator iter = channels_.begin();
304 iter != channels_.end(); ++iter) {
305 if (local_ssrc == iter->second->send_ssrc)
306 return iter->first;
307 }
308 return -1;
309 }
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000310 int GetNumChannels() const { return static_cast<int>(channels_.size()); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311 bool GetPlayout(int channel) {
312 return channels_[channel]->playout;
313 }
314 bool GetSend(int channel) {
315 return channels_[channel]->send;
316 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 bool GetVAD(int channel) {
318 return channels_[channel]->vad;
319 }
Minyue Li7100dcd2015-03-27 05:05:59 +0100320 bool GetOpusDtx(int channel) {
321 return channels_[channel]->opus_dtx;
322 }
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000323 bool GetRED(int channel) {
324 return channels_[channel]->red;
325 }
326 bool GetCodecFEC(int channel) {
327 return channels_[channel]->codec_fec;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 }
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +0000329 int GetMaxEncodingBandwidth(int channel) {
330 return channels_[channel]->max_encoding_bandwidth;
331 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332 bool GetNACK(int channel) {
333 return channels_[channel]->nack;
334 }
335 int GetNACKMaxPackets(int channel) {
336 return channels_[channel]->nack_max_packets;
337 }
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000338 const webrtc::PacketTime& GetLastRtpPacketTime(int channel) {
339 WEBRTC_ASSERT_CHANNEL(channel);
340 return channels_[channel]->last_rtp_packet_time;
341 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 int GetSendCNPayloadType(int channel, bool wideband) {
343 return (wideband) ?
344 channels_[channel]->cn16_type :
345 channels_[channel]->cn8_type;
346 }
347 int GetSendTelephoneEventPayloadType(int channel) {
348 return channels_[channel]->dtmf_type;
349 }
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000350 int GetSendREDPayloadType(int channel) {
351 return channels_[channel]->red_type;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
353 bool CheckPacket(int channel, const void* data, size_t len) {
354 bool result = !CheckNoPacket(channel);
355 if (result) {
356 std::string packet = channels_[channel]->packets.front();
357 result = (packet == std::string(static_cast<const char*>(data), len));
358 channels_[channel]->packets.pop_front();
359 }
360 return result;
361 }
362 bool CheckNoPacket(int channel) {
363 return channels_[channel]->packets.empty();
364 }
365 void TriggerCallbackOnError(int channel_num, int err_code) {
henrikg91d6ede2015-09-17 00:24:34 -0700366 RTC_DCHECK(observer_ != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000367 observer_->CallbackOnError(channel_num, err_code);
368 }
369 void set_playout_fail_channel(int channel) {
370 playout_fail_channel_ = channel;
371 }
372 void set_send_fail_channel(int channel) {
373 send_fail_channel_ = channel;
374 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000375 void set_fail_create_channel(bool fail_create_channel) {
376 fail_create_channel_ = fail_create_channel;
377 }
Henrik Lundin64dad832015-05-11 12:44:23 +0200378 int AddChannel(const webrtc::Config& config) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000379 if (fail_create_channel_) {
380 return -1;
381 }
buildbot@webrtc.orgaf6640f2014-04-28 21:31:51 +0000382 Channel* ch = new Channel();
wu@webrtc.org364f2042013-11-20 21:49:41 +0000383 for (int i = 0; i < NumOfCodecs(); ++i) {
384 webrtc::CodecInst codec;
385 GetCodec(i, codec);
386 ch->recv_codecs.push_back(codec);
387 }
Henrik Lundin64dad832015-05-11 12:44:23 +0200388 if (config.Get<webrtc::NetEqCapacityConfig>().enabled) {
389 ch->neteq_capacity = config.Get<webrtc::NetEqCapacityConfig>().capacity;
390 }
Henrik Lundin5263b3c2015-06-01 10:29:41 +0200391 ch->neteq_fast_accelerate =
392 config.Get<webrtc::NetEqFastAccelerate>().enabled;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000393 channels_[++last_channel_] = ch;
394 return last_channel_;
395 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000396 int GetSendRtpExtensionId(int channel, const std::string& extension) {
397 WEBRTC_ASSERT_CHANNEL(channel);
398 if (extension == kRtpAudioLevelHeaderExtension) {
399 return channels_[channel]->send_audio_level_ext_;
400 } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
401 return channels_[channel]->send_absolute_sender_time_ext_;
402 }
403 return -1;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000404 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000405 int GetReceiveRtpExtensionId(int channel, const std::string& extension) {
406 WEBRTC_ASSERT_CHANNEL(channel);
407 if (extension == kRtpAudioLevelHeaderExtension) {
408 return channels_[channel]->receive_audio_level_ext_;
409 } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
410 return channels_[channel]->receive_absolute_sender_time_ext_;
411 }
412 return -1;
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000413 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000415 int GetNumSetSendCodecs() const { return num_set_send_codecs_; }
416
Minyue2013aec2015-05-13 14:14:42 +0200417 int GetAssociateSendChannel(int channel) {
418 return channels_[channel]->associate_send_channel;
419 }
420
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000421 WEBRTC_STUB(Release, ());
422
423 // webrtc::VoEBase
424 WEBRTC_FUNC(RegisterVoiceEngineObserver, (
425 webrtc::VoiceEngineObserver& observer)) {
426 observer_ = &observer;
427 return 0;
428 }
429 WEBRTC_STUB(DeRegisterVoiceEngineObserver, ());
430 WEBRTC_FUNC(Init, (webrtc::AudioDeviceModule* adm,
431 webrtc::AudioProcessing* audioproc)) {
432 inited_ = true;
433 return 0;
434 }
435 WEBRTC_FUNC(Terminate, ()) {
436 inited_ = false;
437 return 0;
438 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000439 webrtc::AudioProcessing* audio_processing() override {
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +0000440 return &audio_processing_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000442 WEBRTC_FUNC(CreateChannel, ()) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200443 webrtc::Config empty_config;
444 return AddChannel(empty_config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000445 }
Henrik Lundin64dad832015-05-11 12:44:23 +0200446 WEBRTC_FUNC(CreateChannel, (const webrtc::Config& config)) {
447 return AddChannel(config);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000448 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000449 WEBRTC_FUNC(DeleteChannel, (int channel)) {
450 WEBRTC_CHECK_CHANNEL(channel);
Minyue2013aec2015-05-13 14:14:42 +0200451 for (const auto& ch : channels_) {
452 if (ch.second->associate_send_channel == channel) {
453 ch.second->associate_send_channel = -1;
454 }
455 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000456 delete channels_[channel];
457 channels_.erase(channel);
458 return 0;
459 }
460 WEBRTC_STUB(StartReceive, (int channel));
461 WEBRTC_FUNC(StartPlayout, (int channel)) {
462 if (playout_fail_channel_ != channel) {
463 WEBRTC_CHECK_CHANNEL(channel);
464 channels_[channel]->playout = true;
465 return 0;
466 } else {
467 // When playout_fail_channel_ == channel, fail the StartPlayout on this
468 // channel.
469 return -1;
470 }
471 }
472 WEBRTC_FUNC(StartSend, (int channel)) {
473 if (send_fail_channel_ != channel) {
474 WEBRTC_CHECK_CHANNEL(channel);
475 channels_[channel]->send = true;
476 return 0;
477 } else {
478 // When send_fail_channel_ == channel, fail the StartSend on this
479 // channel.
480 return -1;
481 }
482 }
483 WEBRTC_STUB(StopReceive, (int channel));
484 WEBRTC_FUNC(StopPlayout, (int channel)) {
485 WEBRTC_CHECK_CHANNEL(channel);
486 channels_[channel]->playout = false;
487 return 0;
488 }
489 WEBRTC_FUNC(StopSend, (int channel)) {
490 WEBRTC_CHECK_CHANNEL(channel);
491 channels_[channel]->send = false;
492 return 0;
493 }
494 WEBRTC_STUB(GetVersion, (char version[1024]));
495 WEBRTC_STUB(LastError, ());
Minyue2013aec2015-05-13 14:14:42 +0200496 WEBRTC_FUNC(AssociateSendChannel, (int channel,
497 int accociate_send_channel)) {
498 WEBRTC_CHECK_CHANNEL(channel);
499 channels_[channel]->associate_send_channel = accociate_send_channel;
500 return 0;
501 }
ivocb04965c2015-09-09 00:09:43 -0700502 webrtc::RtcEventLog* GetEventLog() { return nullptr; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000503
504 // webrtc::VoECodec
505 WEBRTC_FUNC(NumOfCodecs, ()) {
506 return num_codecs_;
507 }
508 WEBRTC_FUNC(GetCodec, (int index, webrtc::CodecInst& codec)) {
509 if (index < 0 || index >= NumOfCodecs()) {
510 return -1;
511 }
512 const cricket::AudioCodec& c(*codecs_[index]);
513 codec.pltype = c.id;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000514 rtc::strcpyn(codec.plname, sizeof(codec.plname), c.name.c_str());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000515 codec.plfreq = c.clockrate;
516 codec.pacsize = 0;
517 codec.channels = c.channels;
518 codec.rate = c.bitrate;
519 return 0;
520 }
521 WEBRTC_FUNC(SetSendCodec, (int channel, const webrtc::CodecInst& codec)) {
522 WEBRTC_CHECK_CHANNEL(channel);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000523 // To match the behavior of the real implementation.
524 if (_stricmp(codec.plname, "telephone-event") == 0 ||
525 _stricmp(codec.plname, "audio/telephone-event") == 0 ||
526 _stricmp(codec.plname, "CN") == 0 ||
527 _stricmp(codec.plname, "red") == 0 ) {
528 return -1;
529 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000530 channels_[channel]->send_codec = codec;
wu@webrtc.org05e7b442014-04-01 17:44:24 +0000531 ++num_set_send_codecs_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000532 return 0;
533 }
534 WEBRTC_FUNC(GetSendCodec, (int channel, webrtc::CodecInst& codec)) {
535 WEBRTC_CHECK_CHANNEL(channel);
536 codec = channels_[channel]->send_codec;
537 return 0;
538 }
Ivo Creusenadf89b72015-04-29 16:03:33 +0200539 WEBRTC_STUB(SetBitRate, (int channel, int bitrate_bps));
buildbot@webrtc.org7e71b772014-06-13 01:14:01 +0000540 WEBRTC_FUNC(GetRecCodec, (int channel, webrtc::CodecInst& codec)) {
541 WEBRTC_CHECK_CHANNEL(channel);
542 const Channel* c = channels_[channel];
543 for (std::list<std::string>::const_iterator it_packet = c->packets.begin();
544 it_packet != c->packets.end(); ++it_packet) {
545 int pltype;
546 if (!GetRtpPayloadType(it_packet->data(), it_packet->length(), &pltype)) {
547 continue;
548 }
549 for (std::vector<webrtc::CodecInst>::const_iterator it_codec =
550 c->recv_codecs.begin(); it_codec != c->recv_codecs.end();
551 ++it_codec) {
552 if (it_codec->pltype == pltype) {
553 codec = *it_codec;
554 return 0;
555 }
556 }
557 }
558 return -1;
559 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 WEBRTC_FUNC(SetRecPayloadType, (int channel,
561 const webrtc::CodecInst& codec)) {
562 WEBRTC_CHECK_CHANNEL(channel);
563 Channel* ch = channels_[channel];
564 if (ch->playout)
565 return -1; // Channel is in use.
566 // Check if something else already has this slot.
567 if (codec.pltype != -1) {
568 for (std::vector<webrtc::CodecInst>::iterator it =
569 ch->recv_codecs.begin(); it != ch->recv_codecs.end(); ++it) {
570 if (it->pltype == codec.pltype &&
571 _stricmp(it->plname, codec.plname) != 0) {
572 return -1;
573 }
574 }
575 }
576 // Otherwise try to find this codec and update its payload type.
577 for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
578 it != ch->recv_codecs.end(); ++it) {
579 if (strcmp(it->plname, codec.plname) == 0 &&
580 it->plfreq == codec.plfreq) {
581 it->pltype = codec.pltype;
582 it->channels = codec.channels;
583 return 0;
584 }
585 }
586 return -1; // not found
587 }
588 WEBRTC_FUNC(SetSendCNPayloadType, (int channel, int type,
589 webrtc::PayloadFrequencies frequency)) {
590 WEBRTC_CHECK_CHANNEL(channel);
591 if (frequency == webrtc::kFreq8000Hz) {
592 channels_[channel]->cn8_type = type;
593 } else if (frequency == webrtc::kFreq16000Hz) {
594 channels_[channel]->cn16_type = type;
595 }
596 return 0;
597 }
598 WEBRTC_FUNC(GetRecPayloadType, (int channel, webrtc::CodecInst& codec)) {
599 WEBRTC_CHECK_CHANNEL(channel);
600 Channel* ch = channels_[channel];
601 for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
602 it != ch->recv_codecs.end(); ++it) {
603 if (strcmp(it->plname, codec.plname) == 0 &&
604 it->plfreq == codec.plfreq &&
605 it->channels == codec.channels &&
606 it->pltype != -1) {
607 codec.pltype = it->pltype;
608 return 0;
609 }
610 }
611 return -1; // not found
612 }
613 WEBRTC_FUNC(SetVADStatus, (int channel, bool enable, webrtc::VadModes mode,
614 bool disableDTX)) {
615 WEBRTC_CHECK_CHANNEL(channel);
616 if (channels_[channel]->send_codec.channels == 2) {
617 // Replicating VoE behavior; VAD cannot be enabled for stereo.
618 return -1;
619 }
620 channels_[channel]->vad = enable;
621 return 0;
622 }
623 WEBRTC_STUB(GetVADStatus, (int channel, bool& enabled,
624 webrtc::VadModes& mode, bool& disabledDTX));
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +0000625
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000626 WEBRTC_FUNC(SetFECStatus, (int channel, bool enable)) {
627 WEBRTC_CHECK_CHANNEL(channel);
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +0000628 if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
buildbot@webrtc.org3ffa1f92014-07-02 19:51:26 +0000629 // Return -1 if current send codec is not Opus.
630 // TODO(minyue): Excludes other codecs if they support inband FEC.
631 return -1;
632 }
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000633 channels_[channel]->codec_fec = enable;
634 return 0;
635 }
636 WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable)) {
637 WEBRTC_CHECK_CHANNEL(channel);
638 enable = channels_[channel]->codec_fec;
639 return 0;
640 }
buildbot@webrtc.org5d639b32014-09-10 07:57:12 +0000641
642 WEBRTC_FUNC(SetOpusMaxPlaybackRate, (int channel, int frequency_hz)) {
643 WEBRTC_CHECK_CHANNEL(channel);
644 if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
645 // Return -1 if current send codec is not Opus.
646 return -1;
647 }
648 if (frequency_hz <= 8000)
649 channels_[channel]->max_encoding_bandwidth = kOpusBandwidthNb;
650 else if (frequency_hz <= 12000)
651 channels_[channel]->max_encoding_bandwidth = kOpusBandwidthMb;
652 else if (frequency_hz <= 16000)
653 channels_[channel]->max_encoding_bandwidth = kOpusBandwidthWb;
654 else if (frequency_hz <= 24000)
655 channels_[channel]->max_encoding_bandwidth = kOpusBandwidthSwb;
656 else
657 channels_[channel]->max_encoding_bandwidth = kOpusBandwidthFb;
658 return 0;
659 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000660
minyue@webrtc.org9b2e1142015-03-13 09:38:07 +0000661 WEBRTC_FUNC(SetOpusDtx, (int channel, bool enable_dtx)) {
662 WEBRTC_CHECK_CHANNEL(channel);
663 if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
664 // Return -1 if current send codec is not Opus.
665 return -1;
666 }
667 channels_[channel]->opus_dtx = enable_dtx;
668 return 0;
669 }
670
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671 // webrtc::VoEDtmf
672 WEBRTC_FUNC(SendTelephoneEvent, (int channel, int event_code,
673 bool out_of_band = true, int length_ms = 160, int attenuation_db = 10)) {
674 channels_[channel]->dtmf_info.dtmf_event_code = event_code;
675 channels_[channel]->dtmf_info.dtmf_out_of_band = out_of_band;
676 channels_[channel]->dtmf_info.dtmf_length_ms = length_ms;
677 return 0;
678 }
679
680 WEBRTC_FUNC(SetSendTelephoneEventPayloadType,
681 (int channel, unsigned char type)) {
682 channels_[channel]->dtmf_type = type;
683 return 0;
684 };
685 WEBRTC_STUB(GetSendTelephoneEventPayloadType,
686 (int channel, unsigned char& type));
687
688 WEBRTC_STUB(SetDtmfFeedbackStatus, (bool enable, bool directFeedback));
689 WEBRTC_STUB(GetDtmfFeedbackStatus, (bool& enabled, bool& directFeedback));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000690
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000691 WEBRTC_FUNC(PlayDtmfTone,
692 (int event_code, int length_ms = 200, int attenuation_db = 10)) {
693 dtmf_info_.dtmf_event_code = event_code;
694 dtmf_info_.dtmf_length_ms = length_ms;
695 return 0;
696 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000697
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 // webrtc::VoEHardware
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 WEBRTC_FUNC(GetNumOfRecordingDevices, (int& num)) {
700 return GetNumDevices(num);
701 }
702 WEBRTC_FUNC(GetNumOfPlayoutDevices, (int& num)) {
703 return GetNumDevices(num);
704 }
705 WEBRTC_FUNC(GetRecordingDeviceName, (int i, char* name, char* guid)) {
706 return GetDeviceName(i, name, guid);
707 }
708 WEBRTC_FUNC(GetPlayoutDeviceName, (int i, char* name, char* guid)) {
709 return GetDeviceName(i, name, guid);
710 }
711 WEBRTC_STUB(SetRecordingDevice, (int, webrtc::StereoChannel));
712 WEBRTC_STUB(SetPlayoutDevice, (int));
713 WEBRTC_STUB(SetAudioDeviceLayer, (webrtc::AudioLayers));
714 WEBRTC_STUB(GetAudioDeviceLayer, (webrtc::AudioLayers&));
wu@webrtc.org97077a32013-10-25 21:18:33 +0000715 WEBRTC_FUNC(SetRecordingSampleRate, (unsigned int samples_per_sec)) {
716 recording_sample_rate_ = samples_per_sec;
717 return 0;
718 }
719 WEBRTC_FUNC_CONST(RecordingSampleRate, (unsigned int* samples_per_sec)) {
720 *samples_per_sec = recording_sample_rate_;
721 return 0;
722 }
723 WEBRTC_FUNC(SetPlayoutSampleRate, (unsigned int samples_per_sec)) {
724 playout_sample_rate_ = samples_per_sec;
725 return 0;
726 }
727 WEBRTC_FUNC_CONST(PlayoutSampleRate, (unsigned int* samples_per_sec)) {
728 *samples_per_sec = playout_sample_rate_;
729 return 0;
730 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 WEBRTC_STUB(EnableBuiltInAEC, (bool enable));
henrika@webrtc.orga954c072014-12-09 16:22:09 +0000732 virtual bool BuiltInAECIsAvailable() const { return false; }
henrikac14f5ff2015-09-23 14:08:33 +0200733 WEBRTC_STUB(EnableBuiltInAGC, (bool enable));
734 virtual bool BuiltInAGCIsAvailable() const { return false; }
735 WEBRTC_STUB(EnableBuiltInNS, (bool enable));
736 virtual bool BuiltInNSIsAvailable() const { return false; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737
738 // webrtc::VoENetEqStats
minyue@webrtc.orgc0bd7be2015-02-18 15:24:13 +0000739 WEBRTC_FUNC(GetNetworkStatistics, (int channel,
740 webrtc::NetworkStatistics& ns)) {
741 WEBRTC_CHECK_CHANNEL(channel);
742 memcpy(&ns, &kNetStats, sizeof(webrtc::NetworkStatistics));
743 return 0;
744 }
745
wu@webrtc.org24301a62013-12-13 19:17:43 +0000746 WEBRTC_FUNC_CONST(GetDecodingCallStatistics, (int channel,
747 webrtc::AudioDecodingCallStats*)) {
748 WEBRTC_CHECK_CHANNEL(channel);
749 return 0;
750 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751
752 // webrtc::VoENetwork
753 WEBRTC_FUNC(RegisterExternalTransport, (int channel,
754 webrtc::Transport& transport)) {
755 WEBRTC_CHECK_CHANNEL(channel);
756 channels_[channel]->external_transport = true;
757 return 0;
758 }
759 WEBRTC_FUNC(DeRegisterExternalTransport, (int channel)) {
760 WEBRTC_CHECK_CHANNEL(channel);
761 channels_[channel]->external_transport = false;
762 return 0;
763 }
764 WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000765 size_t length)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766 WEBRTC_CHECK_CHANNEL(channel);
767 if (!channels_[channel]->external_transport) return -1;
768 channels_[channel]->packets.push_back(
769 std::string(static_cast<const char*>(data), length));
770 return 0;
771 }
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000772 WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000773 size_t length,
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000774 const webrtc::PacketTime& packet_time)) {
775 WEBRTC_CHECK_CHANNEL(channel);
776 if (ReceivedRTPPacket(channel, data, length) == -1) {
777 return -1;
778 }
779 channels_[channel]->last_rtp_packet_time = packet_time;
780 return 0;
781 }
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000782
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000783 WEBRTC_STUB(ReceivedRTCPPacket, (int channel, const void* data,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000784 size_t length));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000785
786 // webrtc::VoERTP_RTCP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787 WEBRTC_FUNC(SetLocalSSRC, (int channel, unsigned int ssrc)) {
788 WEBRTC_CHECK_CHANNEL(channel);
789 channels_[channel]->send_ssrc = ssrc;
790 return 0;
791 }
792 WEBRTC_FUNC(GetLocalSSRC, (int channel, unsigned int& ssrc)) {
793 WEBRTC_CHECK_CHANNEL(channel);
794 ssrc = channels_[channel]->send_ssrc;
795 return 0;
796 }
797 WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc));
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000798 WEBRTC_FUNC(SetSendAudioLevelIndicationStatus, (int channel, bool enable,
799 unsigned char id)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800 WEBRTC_CHECK_CHANNEL(channel);
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000801 WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
802 channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000803 return 0;
804 }
buildbot@webrtc.org150835e2014-05-06 15:54:38 +0000805 WEBRTC_FUNC(SetReceiveAudioLevelIndicationStatus, (int channel, bool enable,
806 unsigned char id)) {
807 WEBRTC_CHECK_CHANNEL(channel);
808 WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
809 channels_[channel]->receive_audio_level_ext_ = (enable) ? id : -1;
810 return 0;
811 }
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000812 WEBRTC_FUNC(SetSendAbsoluteSenderTimeStatus, (int channel, bool enable,
813 unsigned char id)) {
814 WEBRTC_CHECK_CHANNEL(channel);
815 WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
816 channels_[channel]->send_absolute_sender_time_ext_ = (enable) ? id : -1;
817 return 0;
818 }
819 WEBRTC_FUNC(SetReceiveAbsoluteSenderTimeStatus, (int channel, bool enable,
820 unsigned char id)) {
821 WEBRTC_CHECK_CHANNEL(channel);
822 WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
823 channels_[channel]->receive_absolute_sender_time_ext_ = (enable) ? id : -1;
824 return 0;
825 }
henrike@webrtc.org79047f92014-03-06 23:46:59 +0000826
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827 WEBRTC_STUB(SetRTCPStatus, (int channel, bool enable));
828 WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled));
829 WEBRTC_STUB(SetRTCP_CNAME, (int channel, const char cname[256]));
830 WEBRTC_STUB(GetRTCP_CNAME, (int channel, char cname[256]));
831 WEBRTC_STUB(GetRemoteRTCP_CNAME, (int channel, char* cname));
832 WEBRTC_STUB(GetRemoteRTCPData, (int channel, unsigned int& NTPHigh,
833 unsigned int& NTPLow,
834 unsigned int& timestamp,
835 unsigned int& playoutTimestamp,
836 unsigned int* jitter,
837 unsigned short* fractionLost));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000838 WEBRTC_FUNC(GetRemoteRTCPReportBlocks,
839 (int channel, std::vector<webrtc::ReportBlock>* receive_blocks)) {
840 WEBRTC_CHECK_CHANNEL(channel);
841 webrtc::ReportBlock block;
842 block.source_SSRC = channels_[channel]->send_ssrc;
843 webrtc::CodecInst send_codec = channels_[channel]->send_codec;
844 if (send_codec.pltype >= 0) {
845 block.fraction_lost = (unsigned char)(kFractionLostStatValue * 256);
846 if (send_codec.plfreq / 1000 > 0) {
847 block.interarrival_jitter = kIntStatValue * (send_codec.plfreq / 1000);
848 }
849 block.cumulative_num_packets_lost = kIntStatValue;
850 block.extended_highest_sequence_number = kIntStatValue;
851 receive_blocks->push_back(block);
852 }
853 return 0;
854 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000855 WEBRTC_STUB(GetRTPStatistics, (int channel, unsigned int& averageJitterMs,
856 unsigned int& maxJitterMs,
857 unsigned int& discardedPackets));
858 WEBRTC_FUNC(GetRTCPStatistics, (int channel, webrtc::CallStatistics& stats)) {
859 WEBRTC_CHECK_CHANNEL(channel);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200860 stats.fractionLost = static_cast<int16_t>(kIntStatValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000861 stats.cumulativeLost = kIntStatValue;
862 stats.extendedMax = kIntStatValue;
863 stats.jitterSamples = kIntStatValue;
864 stats.rttMs = kIntStatValue;
865 stats.bytesSent = kIntStatValue;
866 stats.packetsSent = kIntStatValue;
867 stats.bytesReceived = kIntStatValue;
868 stats.packetsReceived = kIntStatValue;
869 return 0;
870 }
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000871 WEBRTC_FUNC(SetREDStatus, (int channel, bool enable, int redPayloadtype)) {
buildbot@webrtc.orgbfa758a2014-06-27 16:04:43 +0000872 return SetFECStatus(channel, enable, redPayloadtype);
873 }
buildbot@webrtc.orgbfa758a2014-06-27 16:04:43 +0000874 // TODO(minyue): remove the below function when transition to SetREDStatus
875 // is finished.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876 WEBRTC_FUNC(SetFECStatus, (int channel, bool enable, int redPayloadtype)) {
877 WEBRTC_CHECK_CHANNEL(channel);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000878 channels_[channel]->red = enable;
879 channels_[channel]->red_type = redPayloadtype;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000880 return 0;
881 }
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000882 WEBRTC_FUNC(GetREDStatus, (int channel, bool& enable, int& redPayloadtype)) {
buildbot@webrtc.orgbfa758a2014-06-27 16:04:43 +0000883 return GetFECStatus(channel, enable, redPayloadtype);
884 }
buildbot@webrtc.orgbfa758a2014-06-27 16:04:43 +0000885 // TODO(minyue): remove the below function when transition to GetREDStatus
886 // is finished.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887 WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable, int& redPayloadtype)) {
888 WEBRTC_CHECK_CHANNEL(channel);
buildbot@webrtc.orgae740dd2014-06-17 10:56:41 +0000889 enable = channels_[channel]->red;
890 redPayloadtype = channels_[channel]->red_type;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000891 return 0;
892 }
893 WEBRTC_FUNC(SetNACKStatus, (int channel, bool enable, int maxNoPackets)) {
894 WEBRTC_CHECK_CHANNEL(channel);
895 channels_[channel]->nack = enable;
896 channels_[channel]->nack_max_packets = maxNoPackets;
897 return 0;
898 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899
900 // webrtc::VoEVideoSync
901 WEBRTC_STUB(GetPlayoutBufferSize, (int& bufferMs));
902 WEBRTC_STUB(GetPlayoutTimestamp, (int channel, unsigned int& timestamp));
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000903 WEBRTC_STUB(GetRtpRtcp, (int, webrtc::RtpRtcp**, webrtc::RtpReceiver**));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904 WEBRTC_STUB(SetInitTimestamp, (int channel, unsigned int timestamp));
905 WEBRTC_STUB(SetInitSequenceNumber, (int channel, short sequenceNumber));
906 WEBRTC_STUB(SetMinimumPlayoutDelay, (int channel, int delayMs));
907 WEBRTC_STUB(SetInitialPlayoutDelay, (int channel, int delay_ms));
908 WEBRTC_STUB(GetDelayEstimate, (int channel, int* jitter_buffer_delay_ms,
909 int* playout_buffer_delay_ms));
910 WEBRTC_STUB_CONST(GetLeastRequiredDelayMs, (int channel));
911
912 // webrtc::VoEVolumeControl
913 WEBRTC_STUB(SetSpeakerVolume, (unsigned int));
914 WEBRTC_STUB(GetSpeakerVolume, (unsigned int&));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915 WEBRTC_STUB(SetMicVolume, (unsigned int));
916 WEBRTC_STUB(GetMicVolume, (unsigned int&));
917 WEBRTC_STUB(SetInputMute, (int, bool));
918 WEBRTC_STUB(GetInputMute, (int, bool&));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000919 WEBRTC_STUB(GetSpeechInputLevel, (unsigned int&));
920 WEBRTC_STUB(GetSpeechOutputLevel, (int, unsigned int&));
921 WEBRTC_STUB(GetSpeechInputLevelFullRange, (unsigned int&));
922 WEBRTC_STUB(GetSpeechOutputLevelFullRange, (int, unsigned int&));
923 WEBRTC_FUNC(SetChannelOutputVolumeScaling, (int channel, float scale)) {
924 WEBRTC_CHECK_CHANNEL(channel);
925 channels_[channel]->volume_scale= scale;
926 return 0;
927 }
928 WEBRTC_FUNC(GetChannelOutputVolumeScaling, (int channel, float& scale)) {
929 WEBRTC_CHECK_CHANNEL(channel);
930 scale = channels_[channel]->volume_scale;
931 return 0;
932 }
933 WEBRTC_FUNC(SetOutputVolumePan, (int channel, float left, float right)) {
934 WEBRTC_CHECK_CHANNEL(channel);
935 channels_[channel]->volume_pan_left = left;
936 channels_[channel]->volume_pan_right = right;
937 return 0;
938 }
939 WEBRTC_FUNC(GetOutputVolumePan, (int channel, float& left, float& right)) {
940 WEBRTC_CHECK_CHANNEL(channel);
941 left = channels_[channel]->volume_pan_left;
942 right = channels_[channel]->volume_pan_right;
943 return 0;
944 }
945
946 // webrtc::VoEAudioProcessing
947 WEBRTC_FUNC(SetNsStatus, (bool enable, webrtc::NsModes mode)) {
948 ns_enabled_ = enable;
949 ns_mode_ = mode;
950 return 0;
951 }
952 WEBRTC_FUNC(GetNsStatus, (bool& enabled, webrtc::NsModes& mode)) {
953 enabled = ns_enabled_;
954 mode = ns_mode_;
955 return 0;
956 }
957
958 WEBRTC_FUNC(SetAgcStatus, (bool enable, webrtc::AgcModes mode)) {
959 agc_enabled_ = enable;
960 agc_mode_ = mode;
961 return 0;
962 }
963 WEBRTC_FUNC(GetAgcStatus, (bool& enabled, webrtc::AgcModes& mode)) {
964 enabled = agc_enabled_;
965 mode = agc_mode_;
966 return 0;
967 }
968
969 WEBRTC_FUNC(SetAgcConfig, (webrtc::AgcConfig config)) {
970 agc_config_ = config;
971 return 0;
972 }
973 WEBRTC_FUNC(GetAgcConfig, (webrtc::AgcConfig& config)) {
974 config = agc_config_;
975 return 0;
976 }
977 WEBRTC_FUNC(SetEcStatus, (bool enable, webrtc::EcModes mode)) {
978 ec_enabled_ = enable;
979 ec_mode_ = mode;
980 return 0;
981 }
982 WEBRTC_FUNC(GetEcStatus, (bool& enabled, webrtc::EcModes& mode)) {
983 enabled = ec_enabled_;
984 mode = ec_mode_;
985 return 0;
986 }
987 WEBRTC_STUB(EnableDriftCompensation, (bool enable))
988 WEBRTC_BOOL_STUB(DriftCompensationEnabled, ())
989 WEBRTC_VOID_STUB(SetDelayOffsetMs, (int offset))
990 WEBRTC_STUB(DelayOffsetMs, ());
991 WEBRTC_FUNC(SetAecmMode, (webrtc::AecmModes mode, bool enableCNG)) {
992 aecm_mode_ = mode;
993 cng_enabled_ = enableCNG;
994 return 0;
995 }
996 WEBRTC_FUNC(GetAecmMode, (webrtc::AecmModes& mode, bool& enabledCNG)) {
997 mode = aecm_mode_;
998 enabledCNG = cng_enabled_;
999 return 0;
1000 }
1001 WEBRTC_STUB(SetRxNsStatus, (int channel, bool enable, webrtc::NsModes mode));
1002 WEBRTC_STUB(GetRxNsStatus, (int channel, bool& enabled,
1003 webrtc::NsModes& mode));
wu@webrtc.org97077a32013-10-25 21:18:33 +00001004 WEBRTC_FUNC(SetRxAgcStatus, (int channel, bool enable,
1005 webrtc::AgcModes mode)) {
1006 channels_[channel]->rx_agc_enabled = enable;
1007 channels_[channel]->rx_agc_mode = mode;
1008 return 0;
1009 }
1010 WEBRTC_FUNC(GetRxAgcStatus, (int channel, bool& enabled,
1011 webrtc::AgcModes& mode)) {
1012 enabled = channels_[channel]->rx_agc_enabled;
1013 mode = channels_[channel]->rx_agc_mode;
1014 return 0;
1015 }
1016
1017 WEBRTC_FUNC(SetRxAgcConfig, (int channel, webrtc::AgcConfig config)) {
1018 channels_[channel]->rx_agc_config = config;
1019 return 0;
1020 }
1021 WEBRTC_FUNC(GetRxAgcConfig, (int channel, webrtc::AgcConfig& config)) {
1022 config = channels_[channel]->rx_agc_config;
1023 return 0;
1024 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001025
1026 WEBRTC_STUB(RegisterRxVadObserver, (int, webrtc::VoERxVadCallback&));
1027 WEBRTC_STUB(DeRegisterRxVadObserver, (int channel));
1028 WEBRTC_STUB(VoiceActivityIndicator, (int channel));
1029 WEBRTC_FUNC(SetEcMetricsStatus, (bool enable)) {
1030 ec_metrics_enabled_ = enable;
1031 return 0;
1032 }
1033 WEBRTC_FUNC(GetEcMetricsStatus, (bool& enabled)) {
1034 enabled = ec_metrics_enabled_;
1035 return 0;
1036 }
1037 WEBRTC_STUB(GetEchoMetrics, (int& ERL, int& ERLE, int& RERL, int& A_NLP));
bjornv@webrtc.orgcc64a9c2015-02-05 12:52:44 +00001038 WEBRTC_STUB(GetEcDelayMetrics, (int& delay_median, int& delay_std,
1039 float& fraction_poor_delays));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001040
1041 WEBRTC_STUB(StartDebugRecording, (const char* fileNameUTF8));
wu@webrtc.org9caf2762013-12-11 18:25:07 +00001042 WEBRTC_STUB(StartDebugRecording, (FILE* handle));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001043 WEBRTC_STUB(StopDebugRecording, ());
1044
1045 WEBRTC_FUNC(SetTypingDetectionStatus, (bool enable)) {
1046 typing_detection_enabled_ = enable;
1047 return 0;
1048 }
1049 WEBRTC_FUNC(GetTypingDetectionStatus, (bool& enabled)) {
1050 enabled = typing_detection_enabled_;
1051 return 0;
1052 }
1053
1054 WEBRTC_STUB(TimeSinceLastTyping, (int& seconds));
1055 WEBRTC_STUB(SetTypingDetectionParameters, (int timeWindow,
1056 int costPerTyping,
1057 int reportingThreshold,
1058 int penaltyDecay,
1059 int typeEventDelay));
1060 int EnableHighPassFilter(bool enable) {
1061 highpass_filter_enabled_ = enable;
1062 return 0;
1063 }
1064 bool IsHighPassFilterEnabled() {
1065 return highpass_filter_enabled_;
1066 }
1067 bool IsStereoChannelSwappingEnabled() {
1068 return stereo_swapping_enabled_;
1069 }
1070 void EnableStereoChannelSwapping(bool enable) {
1071 stereo_swapping_enabled_ = enable;
1072 }
1073 bool WasSendTelephoneEventCalled(int channel, int event_code, int length_ms) {
1074 return (channels_[channel]->dtmf_info.dtmf_event_code == event_code &&
1075 channels_[channel]->dtmf_info.dtmf_out_of_band == true &&
1076 channels_[channel]->dtmf_info.dtmf_length_ms == length_ms);
1077 }
1078 bool WasPlayDtmfToneCalled(int event_code, int length_ms) {
1079 return (dtmf_info_.dtmf_event_code == event_code &&
1080 dtmf_info_.dtmf_length_ms == length_ms);
1081 }
Henrik Lundin64dad832015-05-11 12:44:23 +02001082 int GetNetEqCapacity() const {
1083 auto ch = channels_.find(last_channel_);
1084 ASSERT(ch != channels_.end());
1085 return ch->second->neteq_capacity;
1086 }
Henrik Lundin5263b3c2015-06-01 10:29:41 +02001087 bool GetNetEqFastAccelerate() const {
1088 auto ch = channels_.find(last_channel_);
1089 ASSERT(ch != channels_.end());
1090 return ch->second->neteq_fast_accelerate;
1091 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001092
1093 private:
1094 int GetNumDevices(int& num) {
1095#ifdef WIN32
1096 num = 1;
1097#else
1098 // On non-Windows platforms VE adds a special entry for the default device,
1099 // so if there is one physical device then there are two entries in the
1100 // list.
1101 num = 2;
1102#endif
1103 return 0;
1104 }
1105
1106 int GetDeviceName(int i, char* name, char* guid) {
1107 const char *s;
1108#ifdef WIN32
1109 if (0 == i) {
1110 s = kFakeDeviceName;
1111 } else {
1112 return -1;
1113 }
1114#else
1115 // See comment above.
1116 if (0 == i) {
1117 s = kFakeDefaultDeviceName;
1118 } else if (1 == i) {
1119 s = kFakeDeviceName;
1120 } else {
1121 return -1;
1122 }
1123#endif
1124 strcpy(name, s);
1125 guid[0] = '\0';
1126 return 0;
1127 }
1128
1129 bool inited_;
1130 int last_channel_;
1131 std::map<int, Channel*> channels_;
1132 bool fail_create_channel_;
1133 const cricket::AudioCodec* const* codecs_;
1134 int num_codecs_;
wu@webrtc.org05e7b442014-04-01 17:44:24 +00001135 int num_set_send_codecs_; // how many times we call SetSendCodec().
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001136 bool ec_enabled_;
1137 bool ec_metrics_enabled_;
1138 bool cng_enabled_;
1139 bool ns_enabled_;
1140 bool agc_enabled_;
1141 bool highpass_filter_enabled_;
1142 bool stereo_swapping_enabled_;
1143 bool typing_detection_enabled_;
1144 webrtc::EcModes ec_mode_;
1145 webrtc::AecmModes aecm_mode_;
1146 webrtc::NsModes ns_mode_;
1147 webrtc::AgcModes agc_mode_;
1148 webrtc::AgcConfig agc_config_;
1149 webrtc::VoiceEngineObserver* observer_;
1150 int playout_fail_channel_;
1151 int send_fail_channel_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001152 int recording_sample_rate_;
1153 int playout_sample_rate_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001154 DtmfInfo dtmf_info_;
buildbot@webrtc.orga8d8ad22014-07-16 14:23:08 +00001155 FakeAudioProcessing audio_processing_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001156};
1157
henrike@webrtc.org79047f92014-03-06 23:46:59 +00001158#undef WEBRTC_CHECK_HEADER_EXTENSION_ID
1159
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001160} // namespace cricket
1161
1162#endif // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_